diff --git a/README.md b/README.md index dd03f7099e1..8fb9128d9c1 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ unacceptable behavior to atom@github.com. ## Downloads -Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can +Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can be found on the [releases](https://github.com/atom/electron/releases) page. You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron diff --git a/atom.gyp b/atom.gyp index d4b4f67b631..7b88df4d801 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.34.1', + 'version%': '0.34.2', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 21a553e4d1d..04ed06e0138 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,10 +7,6 @@ #include #include -#if defined(OS_WIN) -#include -#endif - #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_session.h" #include "atom/browser/api/atom_api_web_contents.h" @@ -19,7 +15,7 @@ #include "atom/browser/browser.h" #include "atom/browser/login_handler.h" #include "atom/common/native_mate_converters/callback.h" -#include "atom/common/native_mate_converters/content_converter.h" +#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" @@ -299,13 +295,6 @@ void App::SetDesktopName(const std::string& desktop_name) { #endif } -void App::SetAppUserModelId(const std::string& app_id) { -#if defined(OS_WIN) - base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id); - SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str()); -#endif -} - void App::AllowNTLMCredentialsForAllDomains(bool should_allow) { auto browser_context = static_cast( AtomBrowserMainParts::Get()->browser_context()); @@ -360,6 +349,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::AddRecentDocument, browser)) .SetMethod("clearRecentDocuments", base::Bind(&Browser::ClearRecentDocuments, browser)) + .SetMethod("setAppUserModelId", + base::Bind(&Browser::SetAppUserModelID, browser)) #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) @@ -367,7 +358,6 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("setPath", &App::SetPath) .SetMethod("getPath", &App::GetPath) .SetMethod("setDesktopName", &App::SetDesktopName) - .SetMethod("setAppUserModelId", &App::SetAppUserModelId) .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 63cda4447e3..683093d886c 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -67,7 +67,6 @@ class App : public mate::EventEmitter, const base::FilePath& path); void SetDesktopName(const std::string& desktop_name); - void SetAppUserModelId(const std::string& app_id); void AllowNTLMCredentialsForAllDomains(bool should_allow); bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index f6cc6d79655..e76f26f0d4f 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -12,7 +12,7 @@ #include "atom/browser/net/url_request_fetch_job.h" #include "atom/browser/net/url_request_string_job.h" #include "atom/common/native_mate_converters/callback.h" -#include "atom/common/native_mate_converters/content_converter.h" +#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 900c3e65a37..c329b257a29 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -18,6 +18,7 @@ #include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" @@ -46,6 +47,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/context_menu_params.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/http/http_response_headers.h" @@ -169,11 +171,12 @@ struct Converter { std::string save_type; if (!ConvertFromV8(isolate, val, &save_type)) return false; - if (save_type == "HTMLOnly") { + save_type = base::StringToLowerASCII(save_type); + if (save_type == "htmlonly") { *out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML; - } else if (save_type == "HTMLComplete") { + } else if (save_type == "htmlcomplete") { *out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML; - } else if (save_type == "MHTML") { + } else if (save_type == "mhtml") { *out = content::SAVE_PAGE_TYPE_AS_MHTML; } else { return false; @@ -404,6 +407,15 @@ void WebContents::RendererResponsive(content::WebContents* source) { owner_window()->RendererResponsive(source); } +bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) { + if (!params.custom_context.is_pepper_menu) + return false; + + Emit("pepper-context-menu", std::make_pair(params, web_contents())); + web_contents()->NotifyContextMenuClosed(params.custom_context); + return true; +} + void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 7fa8951106b..ae231cd3c61 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -189,6 +189,7 @@ class WebContents : public mate::TrackableObject, void ExitFullscreenModeForTab(content::WebContents* source) override; void RendererUnresponsive(content::WebContents* source) override; void RendererResponsive(content::WebContents* source) override; + bool HandleContextMenu(const content::ContextMenuParams& params) override; // content::WebContentsObserver: void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 3a2abfb5155..eab9f196715 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,4 +1,5 @@ EventEmitter = require('events').EventEmitter +Menu = require './menu' NavigationController = require './navigation-controller' binding = process.atomBinding 'web_contents' ipc = require 'ipc' @@ -65,6 +66,11 @@ wrapWebContents = (webContents) -> Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value) ipc.emit channel, event, args... + # Handle context menu action request from pepper plugin. + webContents.on 'pepper-context-menu', (event, params) -> + menu = Menu.buildFromTemplate params.menu + menu.popup params.x, params.y + webContents.printToPDF = (options, callback) -> printingSetting = pageRage: [] diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 739921fda90..e80cb4e60e2 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -89,10 +89,6 @@ std::string Browser::GetName() const { void Browser::SetName(const std::string& name) { name_override_ = name; - -#if defined(OS_WIN) - SetAppUserModelID(name); -#endif } bool Browser::OpenFile(const std::string& file_path) { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 8719e18f314..447a526de6d 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -11,12 +11,12 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/observer_list.h" +#include "base/strings/string16.h" #include "atom/browser/browser_observer.h" #include "atom/browser/window_list_observer.h" #if defined(OS_WIN) #include "base/files/file_path.h" -#include "base/strings/string16.h" #endif namespace base { @@ -66,6 +66,9 @@ class Browser : public WindowListObserver { // Clear the recent documents list. void ClearRecentDocuments(); + // Set the application user model ID. + void SetAppUserModelID(const base::string16& name); + #if defined(OS_MACOSX) // Bounce the dock icon. enum BounceType { @@ -100,8 +103,10 @@ class Browser : public WindowListObserver { // Add a custom task to jump list. void SetUserTasks(const std::vector& tasks); - // Set the application user model ID, called when "SetName" is called. - void SetAppUserModelID(const std::string& name); + // Returns the application user model ID, if there isn't one, then create + // one from app's name. + // The returned string managed by Browser, and should not be modified. + PCWSTR GetAppUserModelID(); #endif // Tell the application to open a file. diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index ea8fb7c10c5..25cb9a0a238 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -31,6 +31,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) { void Browser::ClearRecentDocuments() { } +void Browser::SetAppUserModelID(const base::string16& name) { +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 2353aa6c42c..6589057c2c6 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -26,6 +26,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) { void Browser::ClearRecentDocuments() { } +void Browser::SetAppUserModelID(const base::string16& name) { +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index b861af94542..ce36d56b620 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -15,6 +15,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/win/win_util.h" @@ -25,6 +26,8 @@ namespace atom { namespace { +const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1"; + BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { DWORD target_process_id = *reinterpret_cast(param); DWORD process_id = 0; @@ -56,7 +59,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) { if (SUCCEEDED(hr)) { SHARDAPPIDINFO info; info.psi = item; - info.pszAppID = app_user_model_id_.c_str(); + info.pszAppID = GetAppUserModelID(); SHAddToRecentDocs(SHARD_APPIDINFO, &info); } } @@ -66,16 +69,21 @@ void Browser::ClearRecentDocuments() { if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations, NULL, CLSCTX_INPROC_SERVER))) return; - if (FAILED(destinations->SetAppID(app_user_model_id_.c_str()))) + if (FAILED(destinations->SetAppID(GetAppUserModelID()))) return; destinations->RemoveAllDestinations(); } +void Browser::SetAppUserModelID(const base::string16& name) { + app_user_model_id_ = name; + SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); +} + void Browser::SetUserTasks(const std::vector& tasks) { CComPtr destinations; if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList))) return; - if (FAILED(destinations->SetAppID(app_user_model_id_.c_str()))) + if (FAILED(destinations->SetAppID(GetAppUserModelID()))) return; // Start a transaction that updates the JumpList of this application. @@ -117,10 +125,13 @@ void Browser::SetUserTasks(const std::vector& tasks) { destinations->CommitList(); } -void Browser::SetAppUserModelID(const std::string& name) { - app_user_model_id_ = base::string16(L"electron.app."); - app_user_model_id_ += base::UTF8ToUTF16(name); - SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); +PCWSTR Browser::GetAppUserModelID() { + if (app_user_model_id_.empty()) { + SetAppUserModelID(ReplaceStringPlaceholders( + kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr)); + } + + return app_user_model_id_.c_str(); } std::string Browser::GetExecutableFileVersion() const { diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 6b1f95a841a..ae4b161674b 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -2,6 +2,7 @@ ipc = require 'ipc' path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' +IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> @@ -32,14 +33,13 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> # it. meta.id = objectsRegistry.add sender.getId(), value - meta.members = [] - meta.members.push {name: prop, type: typeof field} for prop, field of value + meta.members = ({name, type: typeof field} for name, field of value) else if meta.type is 'buffer' meta.value = Array::slice.call value, 0 else if meta.type is 'promise' - meta.then = valueToMeta(sender, value.then.bind(value)) + meta.then = valueToMeta sender, value.then.bind(value) else if meta.type is 'error' - meta.message = value.message + meta.members = plainObjectToMeta value else if meta.type is 'date' meta.value = value.getTime() else @@ -48,6 +48,10 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta +# Convert object to meta by value. +plainObjectToMeta = (obj) -> + Object.getOwnPropertyNames(obj).map (name) -> {name, value: obj[name]} + # Convert Error into meta data. exceptionToMeta = (error) -> type: 'exception', message: error.message, stack: (error.stack || error) @@ -70,6 +74,13 @@ unwrapArgs = (sender, args) -> returnValue = metaToValue meta.value -> returnValue when 'function' + # Cache the callbacks in renderer. + unless sender.callbacks + sender.callbacks = new IDWeakMap + sender.on 'render-view-deleted', -> + sender.callbacks.clear() + return sender.callbacks.get meta.id if sender.callbacks.has meta.id + rendererReleased = false objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true @@ -77,11 +88,13 @@ unwrapArgs = (sender, args) -> ret = -> if rendererReleased throw new Error("Attempting to call a function in a renderer window - that has been closed or released. Function provided here: #{meta.id}.") + that has been closed or released. Function provided here: #{meta.location}.") sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased + sender.callbacks.remove meta.id sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id + sender.callbacks.set meta.id, ret ret else throw new TypeError("Unknown type: #{meta.type}") diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index aff46850004..a703c01a766 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.34.1 + 0.34.2 CFBundleShortVersionString - 0.34.1 + 0.34.2 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 3adf196e8ba..8401e1d7d09 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,34,1,0 - PRODUCTVERSION 0,34,1,0 + FILEVERSION 0,34,2,0 + PRODUCTVERSION 0,34,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.34.1" + VALUE "FileVersion", "0.34.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.34.1" + VALUE "ProductVersion", "0.34.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/api/atom_api_id_weak_map.cc b/atom/common/api/atom_api_id_weak_map.cc new file mode 100644 index 00000000000..f32e33682df --- /dev/null +++ b/atom/common/api/atom_api_id_weak_map.cc @@ -0,0 +1,79 @@ +// 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/common/api/atom_api_id_weak_map.h" + +#include "atom/common/node_includes.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" + +namespace atom { + +namespace api { + +IDWeakMap::IDWeakMap() { +} + +IDWeakMap::~IDWeakMap() { +} + +void IDWeakMap::Set(v8::Isolate* isolate, + int32_t id, + v8::Local object) { + id_weak_map_.Set(isolate, id, object); +} + +v8::Local IDWeakMap::Get(v8::Isolate* isolate, int32_t id) { + return id_weak_map_.Get(isolate, id).ToLocalChecked(); +} + +bool IDWeakMap::Has(int32_t id) { + return id_weak_map_.Has(id); +} + +void IDWeakMap::Remove(int32_t id) { + id_weak_map_.Remove(id); +} + +void IDWeakMap::Clear() { + id_weak_map_.Clear(); +} + +// static +void IDWeakMap::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("set", &IDWeakMap::Set) + .SetMethod("get", &IDWeakMap::Get) + .SetMethod("has", &IDWeakMap::Has) + .SetMethod("remove", &IDWeakMap::Remove) + .SetMethod("clear", &IDWeakMap::Clear); +} + +// static +mate::Wrappable* IDWeakMap::Create(v8::Isolate* isolate) { + return new IDWeakMap; +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::IDWeakMap; + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + v8::Local constructor = mate::CreateConstructor( + isolate, "IDWeakMap", base::Bind(&IDWeakMap::Create)); + mate::Dictionary id_weak_map(isolate, constructor); + mate::Dictionary dict(isolate, exports); + dict.Set("IDWeakMap", id_weak_map); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_id_weak_map, Initialize) diff --git a/atom/common/api/atom_api_id_weak_map.h b/atom/common/api/atom_api_id_weak_map.h new file mode 100644 index 00000000000..0cf656f455b --- /dev/null +++ b/atom/common/api/atom_api_id_weak_map.h @@ -0,0 +1,44 @@ +// 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_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ +#define ATOM_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ + +#include "atom/common/id_weak_map.h" +#include "native_mate/object_template_builder.h" +#include "native_mate/handle.h" + +namespace atom { + +namespace api { + +class IDWeakMap : public mate::Wrappable { + public: + static mate::Wrappable* Create(v8::Isolate* isolate); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + protected: + IDWeakMap(); + ~IDWeakMap(); + + private: + // Api for IDWeakMap. + void Set(v8::Isolate* isolate, int32_t id, v8::Local object); + v8::Local Get(v8::Isolate* isolate, int32_t id); + bool Has(int32_t id); + void Remove(int32_t id); + void Clear(); + + atom::IDWeakMap id_weak_map_; + + DISALLOW_COPY_AND_ASSIGN(IDWeakMap); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index d4c37f087b1..c546df34f9a 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -1,3 +1,5 @@ +v8Util = process.atomBinding 'v8_util' + module.exports = class CallbacksRegistry constructor: -> @@ -5,6 +7,10 @@ class CallbacksRegistry @callbacks = {} add: (callback) -> + # The callback is already added. + id = v8Util.getHiddenValue callback, 'callbackId' + return id if id? + id = ++@nextId # Capture the location of the function and put it in the ID string, @@ -17,10 +23,11 @@ class CallbacksRegistry continue if location.indexOf('(native)') isnt -1 continue if location.indexOf('atom.asar') isnt -1 [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) - id = "#{filenameAndLine} (#{id})" break @callbacks[id] = callback + v8Util.setHiddenValue callback, 'callbackId', id + v8Util.setHiddenValue callback, 'location', filenameAndLine id get: (id) -> diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 1f8b8dec714..5b1dc4ab44a 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 34 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/id_weak_map.cc b/atom/common/id_weak_map.cc index c5c4b60cac5..a78dcbceba5 100644 --- a/atom/common/id_weak_map.cc +++ b/atom/common/id_weak_map.cc @@ -32,12 +32,18 @@ IDWeakMap::IDWeakMap() : next_id_(0) { IDWeakMap::~IDWeakMap() { } -int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local object) { - int32_t id = GetNextID(); +void IDWeakMap::Set(v8::Isolate* isolate, + int32_t id, + v8::Local object) { auto global = make_linked_ptr(new v8::Global(isolate, object)); ObjectKey* key = new ObjectKey(id, this); global->SetWeak(key, OnObjectGC, v8::WeakCallbackType::kParameter); map_[id] = global; +} + +int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local object) { + int32_t id = GetNextID(); + Set(isolate, id, object); return id; } diff --git a/atom/common/id_weak_map.h b/atom/common/id_weak_map.h index 9fe71ebb616..72c64c6ae5d 100644 --- a/atom/common/id_weak_map.h +++ b/atom/common/id_weak_map.h @@ -19,6 +19,9 @@ class IDWeakMap { IDWeakMap(); ~IDWeakMap(); + // Sets the object to WeakMap with the given |id|. + void Set(v8::Isolate* isolate, int32_t id, v8::Local object); + // Adds |object| to WeakMap and returns its allocated |id|. int32_t Add(v8::Isolate* isolate, v8::Local object); diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index d2a7799fa69..e7f845bba92 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -254,7 +254,8 @@ exports.wrapFsWithAsar = (fs) -> openSync = fs.openSync readFileSync = fs.readFileSync - fs.readFileSync = (p, options) -> + fs.readFileSync = (p, opts) -> + options = opts # this allows v8 to optimize this function [isAsar, asarPath, filePath] = splitPath p return readFileSync.apply this, arguments unless isAsar diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index b6f3a2c1cc0..15a57dea5fb 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -4,30 +4,96 @@ #include "atom/common/native_mate_converters/content_converter.h" +#include + +#include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/string16_converter.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/context_menu_params.h" #include "native_mate/dictionary.h" -#include "net/url_request/url_request.h" + +namespace { + +void ExecuteCommand(content::WebContents* web_contents, + int action, + const content::CustomContextMenuContext& context) { + web_contents->ExecuteCustomContextMenuCommand(action, context); +} + +// Forward declaration for nested recursive call. +v8::Local MenuToV8(v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const std::vector& menu); + +v8::Local MenuItemToV8( + v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const content::MenuItem& item) { + mate::Dictionary v8_item = mate::Dictionary::CreateEmpty(isolate); + switch (item.type) { + case content::MenuItem::CHECKABLE_OPTION: + case content::MenuItem::GROUP: + v8_item.Set("checked", item.checked); + case content::MenuItem::OPTION: + case content::MenuItem::SUBMENU: + v8_item.Set("label", item.label); + v8_item.Set("enabled", item.enabled); + default: + v8_item.Set("type", item.type); + } + if (item.type == content::MenuItem::SUBMENU) + v8_item.Set("submenu", + MenuToV8(isolate, web_contents, context, item.submenu)); + else if (item.action > 0) + v8_item.Set("click", + base::Bind(ExecuteCommand, web_contents, item.action, context)); + return v8_item.GetHandle(); +} + +v8::Local MenuToV8(v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const std::vector& menu) { + std::vector> v8_menu; + for (const auto& menu_item : menu) + v8_menu.push_back(MenuItemToV8(isolate, web_contents, context, menu_item)); + return mate::ConvertToV8(isolate, v8_menu); +} + +} // namespace namespace mate { // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const net::URLRequest* val) { - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("method", val->method()); - dict.Set("url", val->url().spec()); - dict.Set("referrer", val->referrer()); - return mate::ConvertToV8(isolate, dict); +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::MenuItem::Type& val) { + switch (val) { + case content::MenuItem::CHECKABLE_OPTION: + return StringToV8(isolate, "checkbox"); + case content::MenuItem::GROUP: + return StringToV8(isolate, "radio"); + case content::MenuItem::SEPARATOR: + return StringToV8(isolate, "separator"); + case content::MenuItem::SUBMENU: + return StringToV8(isolate, "submenu"); + case content::MenuItem::OPTION: + default: + return StringToV8(isolate, "normal"); + } } // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const net::AuthChallengeInfo* val) { +v8::Local Converter::ToV8( + v8::Isolate* isolate, const ContextMenuParamsWithWebContents& val) { + const auto& params = val.first; mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("isProxy", val->is_proxy); - dict.Set("scheme", val->scheme); - dict.Set("host", val->challenger.host()); - dict.Set("port", static_cast(val->challenger.port())); - dict.Set("realm", val->realm); + dict.Set("x", params.x); + dict.Set("y", params.y); + if (params.custom_context.is_pepper_menu) + dict.Set("menu", MenuToV8(isolate, val.second, params.custom_context, + params.custom_items)); return mate::ConvertToV8(isolate, dict); } diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index 0d4d5fe2cce..7edee24fa14 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -5,25 +5,31 @@ #ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ +#include + +#include "content/public/common/menu_item.h" #include "native_mate/converter.h" -namespace net { -class AuthChallengeInfo; -class URLRequest; +namespace content { +struct ContextMenuParams; +class WebContents; } +using ContextMenuParamsWithWebContents = + std::pair; + namespace mate { template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const net::URLRequest* val); + const content::MenuItem::Type& val); }; template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const net::AuthChallengeInfo* val); + const ContextMenuParamsWithWebContents& val); }; } // namespace mate diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc new file mode 100644 index 00000000000..4796d962660 --- /dev/null +++ b/atom/common/native_mate_converters/net_converter.cc @@ -0,0 +1,34 @@ +// 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/common/native_mate_converters/net_converter.h" + +#include "native_mate/dictionary.h" +#include "net/url_request/url_request.h" + +namespace mate { + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::URLRequest* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("method", val->method()); + dict.Set("url", val->url().spec()); + dict.Set("referrer", val->referrer()); + return mate::ConvertToV8(isolate, dict); +} + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::AuthChallengeInfo* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("isProxy", val->is_proxy); + dict.Set("scheme", val->scheme); + dict.Set("host", val->challenger.host()); + dict.Set("port", static_cast(val->challenger.port())); + dict.Set("realm", val->realm); + return mate::ConvertToV8(isolate, dict); +} + +} // namespace mate diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h new file mode 100644 index 00000000000..352c613eaab --- /dev/null +++ b/atom/common/native_mate_converters/net_converter.h @@ -0,0 +1,31 @@ +// 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_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ + +#include "native_mate/converter.h" + +namespace net { +class AuthChallengeInfo; +class URLRequest; +} + +namespace mate { + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::URLRequest* val); +}; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::AuthChallengeInfo* val); +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 2da68854ad1..10da202da70 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -48,6 +48,7 @@ REFERENCE_MODULE(atom_browser_window); REFERENCE_MODULE(atom_common_asar); REFERENCE_MODULE(atom_common_clipboard); REFERENCE_MODULE(atom_common_crash_reporter); +REFERENCE_MODULE(atom_common_id_weak_map); REFERENCE_MODULE(atom_common_native_image); REFERENCE_MODULE(atom_common_screen); REFERENCE_MODULE(atom_common_shell); diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 8a5565f0656..2de14d54152 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -33,7 +33,7 @@ wrapArgs = (args, visited=[]) -> else if typeof value is 'function' and v8Util.getHiddenValue value, 'returnValue' type: 'function-with-return-value', value: valueToMeta(value()) else if typeof value is 'function' - type: 'function', id: callbacksRegistry.add(value) + type: 'function', id: callbacksRegistry.add(value), location: v8Util.getHiddenValue value, 'location' else type: 'value', value: value @@ -46,7 +46,7 @@ metaToValue = (meta) -> when 'array' then (metaToValue(el) for el in meta.members) when 'buffer' then new Buffer(meta.value) when 'promise' then Promise.resolve(then: metaToValue(meta.then)) - when 'error' then new Error(meta.message) + when 'error' then metaToPlainObject meta when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") @@ -110,6 +110,14 @@ metaToValue = (meta) -> ret +# Construct a plain object from the meta. +metaToPlainObject = (meta) -> + obj = switch meta.type + when 'error' then new Error + else {} + obj[name] = value for {name, value} in meta.members + obj + # Browser calls a callback in renderer. ipc.on 'ATOM_RENDERER_CALLBACK', (id, args) -> callbacksRegistry.apply id, metaToValue(args) diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md index 687dff4bde2..e69e76b1c4c 100644 --- a/docs-translations/es/README.md +++ b/docs-translations/es/README.md @@ -63,9 +63,9 @@ * [Guía de Estilo](development/coding-style.md) * [Estructura de los directorios del Código Fuente](development/source-code-directory-structure.md) -* [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](../../development/atom-shell-vs-node-webkit.md) -* [Repaso del Sistema de Compilación](../../development/build-system-overview.md) -* [Instrucciones de Compilación (Mac)](../../development/build-instructions-osx.md) +* [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Repaso del Sistema de Compilación](development/build-system-overview.md) +* [Instrucciones de Compilación (Mac)](development/build-instructions-osx.md) * [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.md) -* [Instrucciones de Compilación (Linux)](../../development/build-instructions-linux.md) +* [Instrucciones de Compilación (Linux)](development/build-instructions-linux.md) * [Configurando un Servidor de Símbolos en el depurador](../../development/setting-up-symbol-server.md) diff --git a/docs-translations/es/development/atom-shell-vs-node-webkit.md b/docs-translations/es/development/atom-shell-vs-node-webkit.md new file mode 100644 index 00000000000..4072976a2ff --- /dev/null +++ b/docs-translations/es/development/atom-shell-vs-node-webkit.md @@ -0,0 +1,34 @@ +#Diferencias Técnicas entre Electron y NW.js (anteriormente conocido como node-webkit) + +**Nota:Electron se llamaba antes Atom Shell.** + +Como NW.js, Electron proporciona una plataforma para escribir aplicaciones de escritorio con JavaScript y HTML y tiene la integración de nodo para permitir el acceso al sistema de bajo nivel de las páginas web. + +Pero también hay diferencias fundamentales entre los dos proyectos que hacen a Electron un producto totalmente independiente de NW.js: + +**1. Ingreso a la aplicación** + +En NW.js el principal punto de ingreso de una aplicación es una página web. Usted especifica una página principal de URL en el `package.json` y se abre en una ventana del navegador como ventana principal de la aplicación. + +En Electron, el punto de ingreso es un script de JavaScript. En lugar de proporcionar una dirección URL directamente, usted crea manualmente una ventana del navegador y carga un archivo HTML utilizando la API. También es necesario escuchar a los eventos de la ventana para decidir cuándo salir de la aplicación. + +Electron funciona más como el tiempo de ejecución(Runtime) de Node.js. Las Api's de Electron son de bajo nivel asi que puede usarlo para las pruebas del navegador en lugar de usar [PhantomJS.](http://phantomjs.org/) + +**2.Construir un sistema** + +Con el fin de evitar la complejidad de la construcción de todo Chromium, Electron utiliza `libchromiumcontent` para acceder a al contenido Chromium's API. `libchromiumcontent` es solo una liberia compartida que incluye el módulo de contenido de Chromium y todas sus dependencias. Los usuarios no necesitan una máquina potente para construir con Electron. + +**3.Integración de Node** + +In NW.js, the Node integration in web pages requires patching Chromium to work, while in Electron we chose a different way to integrate the libuv loop with each platform's message loop to avoid hacking Chromium. See the node_bindings code for how that was done. + +En NW.js, la integración de Node en las páginas web requiere parchear Chromium para que funcione, mientras que en Electron elegimos una manera diferente para integrar el cilco libuv con cada ciclo de mensaje de las plataformas para evitar el hacking en Chromium. Ver el código `node_bindings` de cómo se hizo. + + +**4. Multi-contexto** + +Si usted es un usuario experimentado NW.js, usted debe estar familiarizado con el concepto de contexto Node y el contexto web. Estos conceptos fueron inventados debido a la forma cómo se implementó NW.js. + +Mediante el uso de la característica [multi-contexto](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/) de Node, Electron no introduce un nuevo contexto JavaScript en páginas web.Resultados de búsqueda + + diff --git a/docs-translations/es/development/build-instructions-linux.md b/docs-translations/es/development/build-instructions-linux.md new file mode 100644 index 00000000000..28ad828fa70 --- /dev/null +++ b/docs-translations/es/development/build-instructions-linux.md @@ -0,0 +1,96 @@ +#Instrucciones de Compilación (Linux) + +Siga las siguientes pautas para la construcción de Electron en Linux. +#Requisitos previos + + * Python 2.7.x. Algunas distribuciones como CentOS siguen utilizando Python 2.6.x por lo que puede que tenga que comprobar su versión de Python con `Python -V`. + * Node.js v0.12.x. Hay varias formas de instalar Node. Puede descargar el código fuente de Node.js y compilar desde las fuentes. Si lo hace, permite la instalación de Node en el directorio personal como usuario estándar. O intentar de repositorios como NodeSource. + * Clang 3.4 o mayor. + * Cabeceras de desarrollo de GTK + y libnotify. + +En Ubuntu, instalar las siguientes bibliotecas: + +`$ 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` + +En Fedora, instale las siguientes bibliotecas: + +`$ 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` + +Otras distribuciones pueden ofrecer paquetes similares para la instalación, a través de gestores de paquetes como el pacman. O puede compilarlo a partir del código fuente. + +#Si utiliza máquinas virtuales para la construcción + +Si usted planea construir Electron en una máquina virtual, necesitará un dispositivo de al menos 25 gigabytes de tamaño. + +#Obteniendo el codigo + +`$ git clone https://github.com/atom/electron.git` + +#Bootstrapping (Arranque) + +The bootstrap script will download all necessary build dependencies and create the build project files. You must have Python 2.7.x for the script to succeed. Downloading certain files can take a long time. Notice that we are using ninja to build Electron so there is no Makefile generated. + +El script de bootstrap descargará todas las dependencias necesarias para construcción y creara los archivos del proyecto de construcción. Debe tener Python 2.7.x para que la secuencia de comandos tenga éxito. La descarga de determinados archivos puede llevar mucho tiempo. Nótese que estamos usando`ninja` para construir Electron por lo que no hay `Makefile` generado. + + $ cd electron + $ ./script/bootstrap.py -v + +#compilación cruzada + +Si usted quiere construir para un `arm` objetivo también debe instalar las siguientes dependencias: + +`$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ g++-arm-linux-gnueabihf` + +And to cross compile for arm or ia32 targets, you should pass the --target_arch parameter to the bootstrap.py script: +cruzar y compilar para `arm` o `ia32` objetivos, debe pasar el parámetro `--target_arch` al script `bootstrap.py`: +`$ ./script/bootstrap.py -v --target_arch=arm` + +#Construcción + +Si a usted le gustaría construir dos objetivos de `Release` y `Debug`: + + `$ ./script/build.py` + + +Este script causará que el ejecutable de Electron se muy grande para ser colocado en el directorio `out / R`. El tamaño del archivo es de más de 1,3 gigabytes. Esto sucede porque el binario de destino lanzamiento contiene los símbolos de depuración. Para reducir el tamaño de archivo, ejecute el script `create-dist.py`: + +`$ ./script/create-dist.py` + +This will put a working distribution with much smaller file sizes in the dist directory. After running the create-dist.py script, you may want to remove the 1.3+ gigabyte binary which is still in out/R. + +Esto pondrá una distribución a trabajar con tamaños de archivo mucho más pequeños en el directorio `dist`. Después de ejecutar el script create-dist.py, es posible que desee quitar el binario 1.3+ gigabyte que todavía está en `out/R`. + +También se puede construir sólo el objetivo `Debug`: +`$ ./script/build.py -c D` + +Después de la construcción está hecho, usted puede encontrar el `Electron` de depuración binario bajo `out / D`. + +#Limpieza + +Para limpiar los archivos de creación: + +`$ ./script/clean.py` + +#Solución de problemas +Asegúrese de que ha instalado todas las dependencias de construcción. + +#Error al cargar bibliotecas compartidas: libtinfo.so.5 + +Prebulit clang will try to link to libtinfo.so.5. Depending on the host architecture, symlink to appropriate libncurses: +preconstruir `clang` intentará enlazar a `libtinfo.so.5`. Dependiendo de la arquitectura anfitrión, enlace simbólico apropiado a `libncurses` : + +`$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5` + +#Pruebas +Pon a prueba tus cambios que ajustan al estilo de codificación proyecto mediante: + +`$ ./script/cpplint.py` + +prueba de funcionalidad utilizando: + +`$ ./script/test.py` diff --git a/docs-translations/es/development/build-instructions-osx.md b/docs-translations/es/development/build-instructions-osx.md new file mode 100644 index 00000000000..6e2d7b7f392 --- /dev/null +++ b/docs-translations/es/development/build-instructions-osx.md @@ -0,0 +1,48 @@ +#Instrucciones de Compilación (Mac) +Siga las siguientes pautas para la construcción de Electron en OS X. + +#Requisitos previos + + `OS X >= 10.8` + `Xcode >= 5.1` + `node.js (external)` + + +Si está utilizando Python descargado de Homebrew, también es necesario instalar los siguientes módulos de python: + `pyobjc` + +#Obtener el Código + +`$ git clone https://github.com/atom/electron.git` + +#Bootstrapping (arranque) + +The bootstrap script will download all necessary build dependencies and create the build project files. Notice that we're using ninja to build Electron so there is no Xcode project generated. + +El script de bootstrap descargará todas las dependencias de construcción necesarias y creara los archivos del proyecto de compilación. notemos que estamos usando `ninja` para construir Electron por lo que no hay un proyecto de Xcode generado. + +`$ cd electron` +`$ ./script/bootstrap.py -v` + +#Construcción +Construir ambos objetivos de `Release` y `Debug`: + +`$ ./script/build.py` + +También sólo se puede construir el objetivo de `Debug`: +`$ ./script/build.py -c D` + +Después de la construcción está hecho, usted puede encontrar `Electron.app` bajo `out / D.` + +#Soporte de 32bit + +Electron sólo puede construirse para un objetivo de 64 bits en OS X y no hay un plan para apoyar a 32 bit OS X en el futuro. + +#Pruebas + +Pon a prueba tus cambios ajustandose al estilo de codificación del proyecto mediante: +`$ ./script/cpplint.py` + +Prueba la funcionalidad usando: + +`$ ./script/test.py` diff --git a/docs-translations/es/development/build-system-overview.md b/docs-translations/es/development/build-system-overview.md new file mode 100644 index 00000000000..1e6a42da84b --- /dev/null +++ b/docs-translations/es/development/build-system-overview.md @@ -0,0 +1,35 @@ +#Repaso del Sistema de construcción +Electron utiliza `gyp` para la generación de proyectos y` ninja` para la contrucción. Las Configuraciones del proyecto se pueden encontrar en los archivos `.gypi` y `.gyp `. + +#Archivos Gyp +los siguientes archivos `gyp` contienen las principales reglas para la contrucción en electron: + + * `atom.gyp` define en si como se compila en Electron. + * `common.gypi` ajusta las configuraciones de generación de Node para construir junto con Chromium. + * `vendor/brightray/brightray.gyp` define cómo se construye `brightray` e incluye las configuraciones predeterminadas para linkear con Chromium. + * `vendor/brightray/brightray.gypi` incluye configuraciones de generación generales sobre la construcción. + +#Construir un componente +Desde Chromium es un proyecto bastante largo, la etapa de enlace final puede tomar pocos minutos, lo que hace que sea difícil para el desarrollo. Con el fin de resolver esto, Chromium introdujo el "componente de construcción", que se basa en construir cada componente como una libreria compartida por separado, haciendo que se enlace muy rápido, pero sacrificando el tamaño del archivo y el rendimiento. + +En Electron tomamos un enfoque muy similar: para versiones de `Debug` (depuración), el binario será linkeado a una versión de la libreria compartida de los componentes de Chromium para lograr un tiempo de enlace rápido; para versiones de `Release` (lanzamiento), el binario será linkeado a las versiones de las librerias estáticas, por lo que puede tener es posible tener un mejor tamaño binario y rendimiento. + +#Bootstrapping minimo (minimo arranque) +Todos los binarios pre-compilados de Chromium (`libchromiumcontent`) son descargados al ejecutar el script de arranque. Por defecto ambas librerias estáticas y librerias compartidas se descargarán y el tamaño final debe estar entre 800 MB y 2 GB dependiendo de la plataforma. + +Por defecto, `libchromiumcontent` se descarga de Amazon Web Services. Si se establece la variable de entorno `LIBCHROMIUMCONTENT_MIRROR`, el bootstrap script se descargará de ella. `libchromiumcontent-qiniu-mirror` es un espejo para el` libchromiumcontent`. Si tiene problemas para acceder a AWS, puede cambiar la dirección de descarga a la misma a través de `exportación LIBCHROMIUMCONTENT_MIRROR = http: // 7xk3d2.dl1.z0.glb.clouddn.com /` + +Si sólo desea construir en Electron rápidamente para pruebas o desarrollo, puede descargar sólo las versiones de librerias compartidas pasando el parámetro `--dev`: + +`$ ./script/bootstrap.py --dev` +`$ ./script/build.py -c D` + +#generación de proyecto de dos frases +Los enlaces de Electron con diferentes conjuntos de librerias en versiones `Release` y `Debug`. `gyp`, sin embargo, no es compatible con la configuración de los diferentes ajustes de enlace para diferentes configuraciones. + +Para evitar que Electron utilice una variable de `gyp` `libchromiumcontent_component` para controlar qué configuraciones de enlace usar y sólo generar un objetivo cuando se ejecute `gyp`. + +#Nombres de destino +A diferencia de la mayoría de los proyectos que utilizan `Release` y `Debug` como nombres de destino, Electron utiliza `R` y `D` en su lugar. Esto se debe a `gyp` bloquea aleatoriamente si sólo hay una configuración de `Release` o `Debug` definidas, y Electron sólo tiene que generar un objetivo a la vez como se ha indicado anteriormente. + +Esto sólo afecta a los desarrolladores, si usted está construyendo Electron para rebranding no se ven afectados. diff --git a/docs-translations/es/tutorial/using-pepper-flash-plugin.md b/docs-translations/es/tutorial/using-pepper-flash-plugin.md index fbb2b6f83aa..53d2d024c1d 100644 --- a/docs-translations/es/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/es/tutorial/using-pepper-flash-plugin.md @@ -31,7 +31,7 @@ app.on('window-all-closed', function() { // Specify flash path. // On Windows, it might be /path/to/pepflashplayer.dll -// On Mac, /path/to/PepperFlashPlayer.plugin +// On OS X, /path/to/PepperFlashPlayer.plugin // On Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); diff --git a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md index a92f61c78e2..dfcca01a5c7 100644 --- a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md @@ -39,7 +39,7 @@ app.on('window-all-closed', function() { // Epecifica o caminho do flash. // No Windows, deve ser /path/to/pepflashplayer.dll -// No Mac, /path/to/PepperFlashPlayer.plugin +// No OS X, /path/to/PepperFlashPlayer.plugin // No Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); diff --git a/docs/api/app.md b/docs/api/app.md index 204155cfa05..00aade7c54a 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -375,6 +375,12 @@ app.on('ready', function() { }); ``` +### `app.setAppUserModelId(id)` _Windows_ + +* `id` String + +Changes the [Application User Model ID][app-user-model-id] to `id`. + ### `app.commandLine.appendSwitch(switch[, value])` Append a switch (with optional `value`) to Chromium's command line. @@ -435,3 +441,4 @@ Sets the application's [dock menu][dock-menu]. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 7649f0f1048..eb0ea375299 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -4,27 +4,34 @@ This module provides an interface for the `Squirrel` auto-updater framework. ## Platform notices -Though `autoUpdater` provides an uniform API for different platforms, there are +Though `autoUpdater` provides a uniform API for different platforms, there are still some subtle differences on each platform. ### OS X -On OS X the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], you -don't need any special setup to make it work. For server-side requirements, you -can read [Server Support][server-support]. +On OS X, the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], +meaning you don't need any special setup to make it work. For server-side +requirements, you can read [Server Support][server-support]. ### Windows -On Windows you have to install your app into user's machine before you can use -the auto-updater, it is recommended to use [grunt-electron-installer][installer] -module to generate a Windows installer. +On Windows, you have to install your app into a user's machine before you can +use the auto-updater, so it is recommended to use +[grunt-electron-installer][installer] module to generate a Windows installer. -The server-side setup is also different from OS X, you can read the documents of +The installer generated with Squirrel will create a shortcut icon with an +[Application User Model ID][app-user-model-id] in the format of +`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, examples are +`com.squirrel.slack.Slack` and `com.squirrel.code.Code`. You have to use the +same ID for your app with `app.setAppUserModelId` API, otherwise Windows will +not be able to pin your app properly in task bar. + +The server-side setup is also different from OS X. You can read the documents of [Squirrel.Windows][squirrel-windows] to get more details. ### Linux -There is not built-in support for auto-updater on Linux, it is recommended to +There is not built-in support for auto-updater on Linux, so it is recommended to use the distribution's package manager to update your app. ## Events @@ -82,12 +89,13 @@ once it is set. Asks the server whether there is an update. You must call `setFeedUrl` before using this API. -### `autoUpdater.quitAndUpdate()` +### `autoUpdater.quitAndInstall()` -Restarts the app and install the update after it has been downloaded. It should -only be called after `update-downloaded` has been emitted. +Restarts the app and installs the update after it has been downloaded. It +should only be called after `update-downloaded` has been emitted. [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows [installer]: https://github.com/atom/grunt-electron-installer +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index d7bf5be374d..fbac6b10863 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -594,7 +594,7 @@ Returns the pathname of the file the window represents. Specifies whether the window’s document has been edited, and the icon in title bar will become grey when set to `true`. -### `win.IsDocumentEdited()` _OS X_ +### `win.isDocumentEdited()` _OS X_ Whether the window's document has been edited. diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 0fadfa37f80..6acfb79884e 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -114,4 +114,6 @@ will be passed via `callback(response)`. Displays a modal dialog that shows an error message. This API can be called safely before the `ready` event the `app` module emits, -it is usually used to report errors in early stage of startup. +it is usually used to report errors in early stage of startup. If called +before the app `ready`event on Linux, the message will be emitted to stderr, +and no GUI dialog will appear. diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 6954fc64b1a..2defedd7418 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -33,6 +33,9 @@ npm install --save-dev electron-rebuild # Every time you run "npm install", run this ./node_modules/.bin/electron-rebuild + +# On Windows if you have trouble, try: +.\node_modules\.bin\electron-rebuild.cmd ``` ### The npm Way diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index 5c8820c2fad..9321798ffca 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -38,7 +38,7 @@ app.on('window-all-closed', function() { // Specify flash path. // On Windows, it might be /path/to/pepflashplayer.dll -// On Mac, /path/to/PepperFlashPlayer.plugin +// On OS X, /path/to/PepperFlashPlayer.plugin // On Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); diff --git a/filenames.gypi b/filenames.gypi index f66485edd19..0e70347309c 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -255,6 +255,8 @@ 'atom/common/api/atom_api_asar.cc', 'atom/common/api/atom_api_clipboard.cc', 'atom/common/api/atom_api_crash_reporter.cc', + 'atom/common/api/atom_api_id_weak_map.cc', + 'atom/common/api/atom_api_id_weak_map.h', 'atom/common/api/atom_api_native_image.cc', 'atom/common/api/atom_api_native_image.h', 'atom/common/api/atom_api_native_image_mac.mm', @@ -314,6 +316,8 @@ 'atom/common/native_mate_converters/gurl_converter.h', 'atom/common/native_mate_converters/image_converter.cc', 'atom/common/native_mate_converters/image_converter.h', + 'atom/common/native_mate_converters/net_converter.cc', + 'atom/common/native_mate_converters/net_converter.h', 'atom/common/native_mate_converters/string16_converter.h', 'atom/common/native_mate_converters/v8_value_converter.cc', 'atom/common/native_mate_converters/v8_value_converter.h', diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 142f06c00ff..1155aa73e83 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -88,3 +88,16 @@ describe 'ipc module', -> w.destroy() done() w.loadUrl 'file://' + path.join(fixtures, 'api', 'send-sync-message.html') + + describe 'remote listeners', -> + it 'can be added and removed correctly', -> + count = 0 + w = new BrowserWindow(show: false) + listener = () -> + count += 1 + w.removeListener 'blur', listener + w.on 'blur', listener + w.emit 'blur' + w.emit 'blur' + assert.equal count, 1 + w.destroy() diff --git a/vendor/native_mate b/vendor/native_mate index b7387da0854..21cda4e7fcf 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit b7387da0854b20d376fdae0d93a01f83d080668d +Subproject commit 21cda4e7fcff592f33f989c1fea575658281711d