diff --git a/.travis.yml b/.travis.yml index 4d4cd5dde9f0..8b4343138994 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ os: - osx env: - TARGET_ARCH=x64 +osx_image: xcode7 matrix: include: diff --git a/atom.gyp b/atom.gyp index f06a0c8251be..c768289f744b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.33.6', + 'version%': '0.33.8', }, 'includes': [ 'filenames.gypi', @@ -64,9 +64,6 @@ 'files': [ '<(PRODUCT_DIR)/<(product_name) Helper.app', '<(PRODUCT_DIR)/<(product_name) Framework.framework', - 'external_binaries/Squirrel.framework', - 'external_binaries/ReactiveCocoa.framework', - 'external_binaries/Mantle.framework', ], }, { @@ -109,7 +106,21 @@ '<@(locale_dirs)', ], }, - ] + ], + 'conditions': [ + ['mas_build==0', { + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks', + 'files': [ + 'external_binaries/Squirrel.framework', + 'external_binaries/ReactiveCocoa.framework', + 'external_binaries/Mantle.framework', + ], + }, + ], + }], + ], }, { # OS=="mac" 'dependencies': [ 'make_locale_paks', @@ -285,12 +296,28 @@ 'vendor/breakpad/breakpad.gyp:breakpad_sender', ], }], # OS=="win" - ['OS=="mac"', { + ['OS=="mac" and mas_build==0', { 'dependencies': [ 'vendor/crashpad/client/client.gyp:crashpad_client', 'vendor/crashpad/handler/handler.gyp:crashpad_handler', ], - }], # OS=="mac" + 'link_settings': { + # Do not link with QTKit for mas build. + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/QTKit.framework', + ], + }, + }], # OS=="mac" and mas_build==0 + ['OS=="mac" and mas_build==1', { + 'defines': [ + 'MAS_BUILD', + ], + 'sources!': [ + 'atom/browser/auto_updater_mac.mm', + 'atom/common/crash_reporter/crash_reporter_mac.h', + 'atom/common/crash_reporter/crash_reporter_mac.mm', + ], + }], # OS=="mac" and mas_build==1 ['OS=="linux"', { 'link_settings': { 'ldflags': [ @@ -393,9 +420,6 @@ 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', - 'external_binaries/Squirrel.framework', - 'external_binaries/ReactiveCocoa.framework', - 'external_binaries/Mantle.framework', ], }, 'mac_bundle': 1, @@ -439,12 +463,6 @@ '<@(copied_libraries)', ], }, - { - 'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources', - 'files': [ - '<(PRODUCT_DIR)/crashpad_handler', - ], - }, ], 'postbuilds': [ { @@ -476,6 +494,25 @@ ], }, ], + 'conditions': [ + ['mas_build==0', { + 'link_settings': { + 'libraries': [ + 'external_binaries/Squirrel.framework', + 'external_binaries/ReactiveCocoa.framework', + 'external_binaries/Mantle.framework', + ], + }, + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources', + 'files': [ + '<(PRODUCT_DIR)/crashpad_handler', + ], + }, + ], + }], + ], }, # target framework { 'target_name': '<(project_name)_helper', diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index e760c01453d4..0931a1b55a41 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -99,7 +99,7 @@ void AtomContentClient::AddAdditionalSchemes( void AtomContentClient::AddPepperPlugins( std::vector* plugins) { auto command_line = base::CommandLine::ForCurrentProcess(); - auto flash_path = command_line->GetSwitchValueNative( + auto flash_path = command_line->GetSwitchValuePath( switches::kPpapiFlashPath); if (flash_path.empty()) return; @@ -108,7 +108,7 @@ void AtomContentClient::AddPepperPlugins( switches::kPpapiFlashVersion); plugins->push_back( - CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); + CreatePepperFlashInfo(flash_path, flash_version)); } } // namespace atom diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index fe3c0e09ae33..639340bcf091 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -5,6 +5,7 @@ #include "atom/app/atom_main_delegate.h" #include +#include #include "atom/app/atom_content_client.h" #include "atom/browser/atom_browser_client.h" @@ -29,6 +30,9 @@ AtomMainDelegate::~AtomMainDelegate() { bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { logging::LoggingSettings settings; #if defined(OS_WIN) + // On Windows the terminal returns immediately, so we add a new line to + // prevent output in the same line as the prompt. + std::wcout << std::endl; #if defined(DEBUG) // Print logging to debug.log on Windows settings.logging_dest = logging::LOG_TO_ALL; @@ -44,8 +48,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { // Only enable logging when --enable-logging is specified. auto command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kEnableLogging)) + if (!command_line->HasSwitch(switches::kEnableLogging)) { settings.logging_dest = logging::LOG_NONE; + logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES); + } logging::InitLogging(settings); diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 2e7596971f48..70595856c494 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -20,6 +20,7 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/node_includes.h" +#include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" @@ -27,6 +28,7 @@ #include "brightray/browser/brightray_paths.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" +#include "content/public/common/content_switches.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/ssl/ssl_cert_request_info.h" @@ -301,6 +303,16 @@ namespace { void AppendSwitch(const std::string& switch_string, mate::Arguments* args) { auto command_line = base::CommandLine::ForCurrentProcess(); + + if (switch_string == atom::switches::kPpapiFlashPath || + switch_string == atom::switches::kClientCertificate || + switch_string == switches::kLogNetLog) { + base::FilePath path; + args->GetNext(&path); + command_line->AppendSwitchPath(switch_string, path); + return; + } + std::string value; if (args->GetNext(&value)) command_line->AppendSwitchASCII(switch_string, value); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f6433ca635cd..0b8a9882cd1b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -31,6 +31,7 @@ #include "chrome/browser/printing/print_view_manager_basic.h" #include "chrome/browser/printing/print_preview_message_handler.h" #include "content/common/view_messages.h" +#include "content/public/browser/browser_plugin_guest_manager.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_details.h" @@ -51,6 +52,7 @@ #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/base/l10n/l10n_util.h" #include "atom/common/node_includes.h" @@ -62,9 +64,21 @@ struct PrintSettings { }; void SetUserAgentInIO(scoped_refptr getter, + std::string accept_lang, std::string user_agent) { getter->GetURLRequestContext()->set_http_user_agent_settings( - new net::StaticHttpUserAgentSettings("en-us,en", user_agent)); + new net::StaticHttpUserAgentSettings( + net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang), + user_agent)); +} + +bool NotifyZoomLevelChanged( + double level, content::WebContents* guest_web_contents) { + guest_web_contents->SendToAllFrames( + new AtomViewMsg_SetZoomLevel(MSG_ROUTING_NONE, level)); + + // Return false to iterate over all guests. + return false; } } // namespace @@ -133,7 +147,6 @@ struct Converter { std::string value; while (headers->EnumerateHeaderLines(&iter, &key, &value)) { key = base::StringToLowerASCII(key); - value = base::StringToLowerASCII(value); if (response_headers.HasKey(key)) { base::ListValue* values = nullptr; if (response_headers.GetList(key, &values)) @@ -528,6 +541,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage) IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync, OnRendererMessageSync) + IPC_MESSAGE_HANDLER(AtomViewHostMsg_ZoomLevelChanged, OnZoomLevelChanged) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -637,8 +651,10 @@ void WebContents::SetUserAgent(const std::string& user_agent) { web_contents()->SetUserAgentOverride(user_agent); scoped_refptr getter = web_contents()->GetBrowserContext()->GetRequestContext(); + + auto accept_lang = l10n_util::GetApplicationLocale(""); getter->GetNetworkTaskRunner()->PostTask(FROM_HERE, - base::Bind(&SetUserAgentInIO, getter, user_agent)); + base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent)); } std::string WebContents::GetUserAgent() { @@ -1033,6 +1049,15 @@ void WebContents::OnRendererMessageSync(const base::string16& channel, EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args); } +void WebContents::OnZoomLevelChanged(double level) { + auto manager = web_contents()->GetBrowserContext()->GetGuestManager(); + if (!manager) + return; + manager->ForEachGuest(web_contents(), + base::Bind(&NotifyZoomLevelChanged, + level)); +} + // static mate::Handle WebContents::CreateFrom( v8::Isolate* isolate, content::WebContents* web_contents) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index bbf331848c55..01075c450a53 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -247,6 +247,10 @@ class WebContents : public mate::TrackableObject, const base::ListValue& args, IPC::Message* message); + // Called when guests need to be notified of + // embedders' zoom level change. + void OnZoomLevelChanged(double level); + v8::Global session_; v8::Global devtools_web_contents_; diff --git a/atom/browser/auto_updater.cc b/atom/browser/auto_updater.cc index fd3d412f9bb0..7ebae510e9f8 100644 --- a/atom/browser/auto_updater.cc +++ b/atom/browser/auto_updater.cc @@ -16,4 +16,12 @@ void AutoUpdater::SetDelegate(AutoUpdaterDelegate* delegate) { delegate_ = delegate; } +#if defined(OS_MACOSX) && defined(MAS_BUILD) +void AutoUpdater::SetFeedURL(const std::string& url) { +} + +void AutoUpdater::CheckForUpdates() { +} +#endif + } // namespace auto_updater diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 1b92685d13a2..9cb468182d4d 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -18,6 +18,9 @@ for (var i = 0; i < argv.length; i++) { if (argv[i] == '--version' || argv[i] == '-v') { option.version = true; break; + } else if (argv[i].match(/^--app=/)) { + option.file = argv[i].split('=')[1]; + break; } else if (argv[i] == '--help' || argv[i] == '-h') { option.help = true; break; @@ -260,7 +263,7 @@ if (option.file && !option.webdriver) { helpMessage += "A path to an Electron application may be specified. The path must be to \n"; helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n"; helpMessage += "Options:\n"; - helpMessage += " -r, --require Module to preload (option can be repeated)"; + helpMessage += " -r, --require Module to preload (option can be repeated)\n"; helpMessage += " -h, --help Print this usage message.\n"; helpMessage += " -v, --version Print the version."; console.log(helpMessage); diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index 9a5c0ca349ae..5de3ad3b042e 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -67,7 +67,7 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) -> guestContents = BrowserWindow.fromId(guestId)?.webContents if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*' - guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin + guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, targetOrigin ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) -> embedder = v8Util.getHiddenValue event.sender, 'embedder' diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index b394c0fecc28..67630a1bd6fa 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -18,20 +18,6 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') -if process.platform is 'win32' - # Redirect node's console to use our own implementations, since node can not - # handle console output when running as GUI program. - print = (args...) -> - process.log util.format(args...) - console.log = console.error = console.warn = print - process.stdout.write = process.stderr.write = print - - # Always returns EOF for stdin stream. - Readable = require('stream').Readable - stdin = new Readable - stdin.push null - process.__defineGetter__ 'stdin', -> stdin - # Don't quit on fatal error. process.on 'uncaughtException', (error) -> # Do nothing if the user has a custom uncaught exception handler. diff --git a/atom/browser/mac/atom_application.mm b/atom/browser/mac/atom_application.mm index 9eaabc410bda..cc9c6accc83d 100644 --- a/atom/browser/mac/atom_application.mm +++ b/atom/browser/mac/atom_application.mm @@ -43,11 +43,20 @@ atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url)); } +- (bool)voiceOverEnabled { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults addSuiteNamed:@"com.apple.universalaccess"]; + [defaults synchronize]; + + return [defaults boolForKey:@"voiceOverOnOffKey"]; +} + - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { // Undocumented attribute that VoiceOver happens to set while running. // Chromium uses this too, even though it's not exactly right. if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) { - [self updateAccessibilityEnabled:[value boolValue]]; + bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]); + [self updateAccessibilityEnabled:enableAccessibility]; } return [super accessibilitySetValue:value forAttribute:attribute]; } diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 50e019c1c77e..f4725715526b 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,11 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.33.6 + 0.33.8 + CFBundleShortVersionString + 0.33.8 + LSApplicationCategoryType + public.app-category.developer-tools LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index b1aba451dcf6..08af14987eee 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,33,6,0 - PRODUCTVERSION 0,33,6,0 + FILEVERSION 0,33,8,0 + PRODUCTVERSION 0,33,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.33.6" + VALUE "FileVersion", "0.33.8" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.33.6" + VALUE "ProductVersion", "0.33.8" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index b32df3cef39d..274e1f533eb3 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -30,6 +30,12 @@ IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync, base::ListValue /* arguments */, base::string16 /* result (in JSON) */) +IPC_MESSAGE_ROUTED1(AtomViewHostMsg_ZoomLevelChanged, + double /* level */) + +IPC_MESSAGE_ROUTED1(AtomViewMsg_SetZoomLevel, + double /* level */) + IPC_MESSAGE_ROUTED2(AtomViewMsg_Message, base::string16 /* channel */, base::ListValue /* arguments */) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index d6fb355e09d8..06fc30e7e3cd 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -6,6 +6,7 @@ #include #include +#include #include "atom/common/atom_version.h" #include "atom/common/chrome_version.h" @@ -40,7 +41,7 @@ void FatalErrorCallback(const char* location, const char* message) { } void Log(const base::string16& message) { - logging::LogMessage("CONSOLE", 0, 0).stream() << message; + std::cout << message; } } // namespace @@ -71,6 +72,10 @@ void AtomBindings::BindTo(v8::Isolate* isolate, // Do not warn about deprecated APIs. dict.Set("noDeprecation", true); +#if defined(MAS_BUILD) + dict.Set("mas", true); +#endif + mate::Dictionary versions; if (dict.Get("versions", &versions)) { versions.Set(ATOM_PROJECT_NAME, ATOM_VERSION_STRING); diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 8078551b90ed..205d512b2b52 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 33 -#define ATOM_PATCH_VERSION 6 +#define ATOM_PATCH_VERSION 8 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/crash_reporter/crash_reporter.cc b/atom/common/crash_reporter/crash_reporter.cc index 59b7fd51e45e..b87ce54acd51 100644 --- a/atom/common/crash_reporter/crash_reporter.cc +++ b/atom/common/crash_reporter/crash_reporter.cc @@ -64,4 +64,23 @@ CrashReporter::GetUploadedReports(const std::string& path) { return result; } +void CrashReporter::InitBreakpad(const std::string& product_name, + const std::string& version, + const std::string& company_name, + const std::string& submit_url, + bool auto_submit, + bool skip_system_crash_handler) { +} + +void CrashReporter::SetUploadParameters() { +} + +#if defined(OS_MACOSX) && defined(MAS_BUILD) +// static +CrashReporter* CrashReporter::GetInstance() { + static CrashReporter crash_reporter; + return &crash_reporter; +} +#endif + } // namespace crash_reporter diff --git a/atom/common/crash_reporter/crash_reporter.h b/atom/common/crash_reporter/crash_reporter.h index c7d58ca3aa76..98832fea45de 100644 --- a/atom/common/crash_reporter/crash_reporter.h +++ b/atom/common/crash_reporter/crash_reporter.h @@ -40,8 +40,8 @@ class CrashReporter { const std::string& company_name, const std::string& submit_url, bool auto_submit, - bool skip_system_crash_handler) = 0; - virtual void SetUploadParameters() = 0; + bool skip_system_crash_handler); + virtual void SetUploadParameters(); StringMap upload_parameters_; bool is_browser_; diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index a91e614fc6dd..7d3a1277cb8b 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -152,6 +152,10 @@ v8::Local V8ValueConverter::ToV8ValueImpl( return ToV8Object(isolate, static_cast(value)); + case base::Value::TYPE_BINARY: + return ToArrayBuffer(isolate, + static_cast(value)); + default: LOG(ERROR) << "Unexpected value type: " << value->GetType(); return v8::Null(isolate); @@ -200,6 +204,13 @@ v8::Local V8ValueConverter::ToV8Object( return result.GetHandle(); } +v8::Local V8ValueConverter::ToArrayBuffer( + v8::Isolate* isolate, const base::BinaryValue* value) const { + return node::Buffer::Copy(isolate, + value->GetBuffer(), + value->GetSize()).ToLocalChecked(); +} + base::Value* V8ValueConverter::FromV8ValueImpl( FromV8ValueState* state, v8::Local val, diff --git a/atom/common/native_mate_converters/v8_value_converter.h b/atom/common/native_mate_converters/v8_value_converter.h index db108ad9b043..2b695b43747b 100644 --- a/atom/common/native_mate_converters/v8_value_converter.h +++ b/atom/common/native_mate_converters/v8_value_converter.h @@ -41,6 +41,9 @@ class V8ValueConverter { v8::Local ToV8Object( v8::Isolate* isolate, const base::DictionaryValue* dictionary) const; + v8::Local ToArrayBuffer( + v8::Isolate* isolate, + const base::BinaryValue* value) const; base::Value* FromV8ValueImpl(FromV8ValueState* state, v8::Local value, diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index 1aa75effd35b..2f9e2b764236 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -20,7 +20,7 @@ void ShowItemInFolder(const base::FilePath& full_path) { DCHECK([NSThread isMainThread]); NSString* path_string = base::SysUTF8ToNSString(full_path.value()); if (!path_string || ![[NSWorkspace sharedWorkspace] selectFile:path_string - inFileViewerRootedAtPath:nil]) + inFileViewerRootedAtPath:@""]) LOG(WARNING) << "NSWorkspace failed to select file " << full_path.value(); } diff --git a/atom/common/resources/mac/Info.plist b/atom/common/resources/mac/Info.plist index 332babe979e6..7b56a46470ea 100644 --- a/atom/common/resources/mac/Info.plist +++ b/atom/common/resources/mac/Info.plist @@ -2,12 +2,12 @@ - CFBundleExecutable - ${PRODUCT_NAME} Framework CFBundleIdentifier ${ATOM_BUNDLE_ID} CFBundleName - ${PRODUCT_NAME} Framework + ${PRODUCT_NAME} + CFBundleExecutable + ${PRODUCT_NAME} CFBundlePackageType FMWK NSSupportsAutomaticGraphicsSwitching diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 4506658588c2..69613043043d 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -4,11 +4,13 @@ #include "atom/renderer/api/atom_api_web_frame.h" +#include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" #include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_view.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "third_party/WebKit/public/web/WebDocument.h" @@ -34,6 +36,10 @@ void WebFrame::SetName(const std::string& name) { } double WebFrame::SetZoomLevel(double level) { + auto render_view = content::RenderView::FromWebView(web_frame_->view()); + // Notify guests if any for zoom level change. + render_view->Send( + new AtomViewHostMsg_ZoomLevelChanged(MSG_ROUTING_NONE, level)); return web_frame_->view()->setZoomLevel(level); } diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index b99372bf816d..eeadabcba737 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -6,6 +6,7 @@ #include +#include "atom/common/api/api_messages.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/node_bindings.h" #include "atom/common/node_includes.h" @@ -21,11 +22,13 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread.h" +#include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/web/WebCustomElement.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginParams.h" #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" +#include "third_party/WebKit/public/web/WebView.h" #if defined(OS_WIN) #include @@ -64,6 +67,22 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { render_frame()->GetWebFrame(), context); } + bool OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(AtomRenderFrameObserver, message) + IPC_MESSAGE_HANDLER(AtomViewMsg_SetZoomLevel, OnSetZoomLevel) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; + } + + void OnSetZoomLevel(double level) { + auto view = render_frame()->GetWebFrame()->view(); + if (view) + view->setZoomLevel(level); + } + private: AtomRendererClient* renderer_client_; diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md index 497cc4e05ccf..6e2374cfd449 100644 --- a/docs-translations/es/README.md +++ b/docs-translations/es/README.md @@ -1,32 +1,33 @@ ## Guías -* [Distribución de aplicaciones](tutorial/application-distribution.md) -* [Empaquetamiento de aplicaciones](tutorial/application-packaging.md) -* [Utilizando módulos nativos](tutorial/using-native-node-modules.md) -* [Depurando el proceso principal](tutorial/debugging-main-process.md) +* [Platfaformas Soportadas](tutorial/supported-platforms.md) +* [Distribución de la Aplicacion](tutorial/application-distribution.md) +* [Empaquetamiento de la Aplicacion](tutorial/application-packaging.md) +* [Utilizando Módulos Node Nativos](tutorial/using-native-node-modules.md) +* [Depurando el Proceso Principal](tutorial/debugging-main-process.md) * [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver.md) * [Extensión DevTools](tutorial/devtools-extension.md) -* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin.md) +* [Utilizando el plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md) ## Tutoriales -* [Introducción](../../docs/tutorial/quick-start.md) -* [Integración con el entorno de escritorio](../../docs/tutorial/desktop-environment-integration.md) -* [Detección del evento en línea/fuera de línea](../../docs/tutorial/online-offline-events.md) +* [Introducción](tutorial/quick-start.md) +* [Integración con el entorno de escritorio](tutorial/desktop-environment-integration.md) +* [Detección del evento en línea/fuera de línea](tutorial/online-offline-events.md) -## API +## Referencias a la API -* [Sinopsis](../../docs/api/synopsis.md) -* [Proceso](../../docs/api/process.md) -* [Parámetros CLI soportados (Chrome)](../../docs/api/chrome-command-line-switches.md) +* [Sinopsis](api/synopsis.md) +* [Proceso](api/process.md) +* [Parámetros CLI soportados (Chrome)](api/chrome-command-line-switches.md) -Elementos DOM customizados: +### Elementos DOM personalizados: * [Objeto `File`](../../docs/api/file-object.md) * [Etiqueta ``](../../docs/api/web-view-tag.md) * [Función `window.open`](../../docs/api/window-open.md) -Módulos del proceso principal: +### Módulos del Proceso Principal: * [app](../../docs/api/app.md) * [auto-updater](../../docs/api/auto-updater.md) @@ -34,21 +35,23 @@ Módulos del proceso principal: * [content-tracing](../../docs/api/content-tracing.md) * [dialog](../../docs/api/dialog.md) * [global-shortcut](../../docs/api/global-shortcut.md) -* [ipc (main process)](../../docs/api/ipc-main-process.md) +* [ipc (proceso principal)](../../docs/api/ipc-main-process.md) * [menu](../../docs/api/menu.md) * [menu-item](../../docs/api/menu-item.md) * [power-monitor](../../docs/api/power-monitor.md) * [power-save-blocker](../../docs/api/power-save-blocker.md) * [protocol](../../docs/api/protocol.md) +* [session](../../docs/api/session.md) +* [web-contents](../../docs/api/web-contents.md) * [tray](../../docs/api/tray.md) -Módulos del renderer (página web): +### Módulos del proceso de renderizado (Página Web): -* [ipc (renderer)](../../docs/api/ipc-renderer.md) +* [ipc (renderizador)](../../docs/api/ipc-renderer.md) * [remote](../../docs/api/remote.md) * [web-frame](../../docs/api/web-frame.md) -Módulos de ambos procesos: +### Módulos de Ambos Procesos: * [clipboard](../../docs/api/clipboard.md) * [crash-reporter](../../docs/api/crash-reporter.md) @@ -58,11 +61,11 @@ Módulos de ambos procesos: ## Desarrollo -* [Guía de estilo](../../docs/development/coding-style.md) -* [Estructura de directorio](../../docs/development/source-code-directory-structure.md) -* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) -* [Sistema de compilación](../../docs/development/build-system-overview.md) -* [Instrucciones de compilación (Mac)](../../docs/development/build-instructions-osx.md) -* [Instrucciones de compilación (Windows)](../../docs/development/build-instructions-windows.md) -* [Instrucciones de compilación (Linux)](../../docs/development/build-instructions-linux.md) -* [Configurando un servidor de símbolos en el depurador](../../docs/development/setting-up-symbol-server.md) +* [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) +* [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.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/api/chrome-command-line-switches.md b/docs-translations/es/api/chrome-command-line-switches.md new file mode 100644 index 000000000000..c063869adf95 --- /dev/null +++ b/docs-translations/es/api/chrome-command-line-switches.md @@ -0,0 +1,119 @@ +# Parámetros CLI soportados (Chrome) + +Esta página lista las líneas de comandos usadas por el navegador Chrome que también son +soportadas por Electron. Puedes usar [app.commandLine.appendSwitch][append-switch] para +anexarlas en el script principal de tu aplicación antes de que el evento [ready][ready] del +modulo [app][app] sea emitido: + +```javascript +var app = require('app'); +app.commandLine.appendSwitch('remote-debugging-port', '8315'); +app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); + +app.on('ready', function() { + // Your code here +}); +``` + +## --client-certificate=`path` + +Establece el `path` del archivo de certificado del cliente. + +## --ignore-connections-limit=`domains` + +Ignora el límite de conexiones para la lista de `domains` separados por `,`. + +## --disable-http-cache + +Deshabilita la cacheé del disco para las peticiones HTTP. + +## --remote-debugging-port=`port` + +Habilita la depuración remota a través de HTTP en el puerto especificado. + +## --proxy-server=`address:port` + +Usa un servidor proxy especificado, que sobreescribe la configuración del sistema. +Este cambio solo afecta peticiones HTTP y HTTPS. + +## --proxy-pac-url=`url` + +Utiliza el script PAC en la `url` especificada. + +## --no-proxy-server + +No usa un servidor proxy y siempre establece conexiones directas. Anula cualquier +otra bandera de servidor proxy bandera que se pase. + +## --host-rules=`rules` + +Una lista separada por comas de `rules` (reglas) que controlan cómo se asignan los +nombres de host. + +Por ejemplo: + +* `MAP * 127.0.0.1` Obliga a todos los nombres de host a ser asignados a 127.0.0.1 +* `MAP *.google.com proxy` Obliga todos los subdominios google.com a resolverse con + "proxy". +* `MAP test.com [::1]:77` Obliga a resolver "test.com" con un bucle invertido de IPv6. + También obligará a que el puerto de la dirección respuesta sea 77. +* `MAP * baz, EXCLUDE www.google.com` Reasigna todo a "baz", excepto a "www.google.com". + +Estas asignaciones especifican el host final en una petición de red (Anfitrión de la conexión TCP +y de resolución de conexión directa, y el `CONNECT` en una conexión proxy HTTP, y el host final de +la conexión proxy `SOCKS`). + +## --host-resolver-rules=`rules` + +Como `--host-rules` pero estas `rules` solo se aplican al solucionador. + +[app]: app.md +[append-switch]: app.md#appcommandlineappendswitchswitch-value +[ready]: app.md#event-ready + +## --ignore-certificate-errors + +Ignora errores de certificado relacionados. + +## --ppapi-flash-path=`path` + +Asigna la ruta `path` del pepper flash plugin. + +## --ppapi-flash-version=`version` + +Asigna la versión `version` del pepper flash plugin. + +## --log-net-log=`path` + +Permite guardar y escribir eventos de registros de red en `path`. + +## --ssl-version-fallback-min=`version` + +Establece la versión mínima de SSL/TLS ("tls1", "tls1.1" o "tls1.2") que +el repliegue de TLC aceptará. + +## --enable-logging + +Imprime el registro de Chromium en consola. + +Este cambio no puede ser usado en `app.commandLine.appendSwitch` ya que se analiza antes de que la +aplicación del usuario este cargada. + +## --v=`log_level` + +Da el maximo nivel activo de V-logging por defecto; 0 es el predeterminado. Valores positivos +son normalmente usados para los niveles de V-logging. + +Este modificador sólo funciona cuando también se pasa `--enable-logging`. + +## --vmodule=`pattern` + +Da los niveles máximos de V-logging por módulo para sobreescribir el valor dado por +`--v`. Ej. `my_module=2,foo*=3` cambiaria el nivel de registro para todo el código +el archivos de origen `my_module.*` y `foo*.*`. + +Cualquier patron que contiene un slash o un slash invertido será probado contra toda la ruta +y no sólo con el módulo. Ej. `*/foo/bar/*=2` cambiaría el nivel de registro para todo el código +en los archivos origen bajo un directorio `foo/bar`. + +Este modificador sólo funciona cuando también se pasa `--enable-logging`. diff --git a/docs-translations/es/api/process.md b/docs-translations/es/api/process.md new file mode 100644 index 000000000000..e03ef5fa1c36 --- /dev/null +++ b/docs-translations/es/api/process.md @@ -0,0 +1,47 @@ +# process + +El objeto `process` en Electron tiene las siguientes diferencias con respecto +al node convencional: + +* `process.type` String - El tipo del proceso puede ser `browser` (ej. proceso + principal) o `renderer`. +* `process.versions['electron']` String - Versión de Electron. +* `process.versions['chrome']` String - Versión de Chromium. +* `process.resourcesPath` String - Ruta al código fuente JavaScript. + +## Events + +### Event: 'loaded' + +Se emite cuando Electron ha cargado su script de inicialización interna y +está comenzando a cargar la página web o el script principal. + +Puede ser usado por el script precargado para añadir de nuevo los símbolos globales +de Node eliminados, al alcance global cuando la integración de Node está apagada: + +```js +// preload.js +var _setImmediate = setImmediate; +var _clearImmediate = clearImmediate; +process.once('loaded', function() { + global.setImmediate = _setImmediate; + global.clearImmediate = _clearImmediate; +}); +``` + +## Methods + +El objeto `process` tiene los siguientes métodos: + +### `process.hang` + +Interrumpe el hilo principal del proceso actual. + + +### process.setFdLimit(maxDescriptors) _OS X_ _Linux_ + +* `maxDescriptors` Integer + +Establece el límite dinámico del descriptor del archivo en `maxDescriptors` +o en el límite estricto del Sistema Operativo, el que sea menor para el +proceso actual. diff --git a/docs-translations/es/api/synopsis.md b/docs-translations/es/api/synopsis.md new file mode 100644 index 000000000000..0da368dea459 --- /dev/null +++ b/docs-translations/es/api/synopsis.md @@ -0,0 +1,47 @@ +# Synopsis + +Todos los [Módulos integrados de Node.js](http://nodejs.org/api/) se encuentran +disponibles en Electron y módulos de terceros son támbien totalmente compatibles +(incluyendo los [módulos nativos](../tutorial/using-native-node-modules.md)). + +Electron también provee algunos módulos integrados adicionales para desarrollar +aplicaciones nativas de escritorio. Algunos módulos sólo se encuentran disponibles +en el proceso principal, algunos sólo en el proceso renderer (pagina web), y +algunos pueden ser usados en ambos procesos. + +La regla básica es: Si un módulo es +[GUI](https://es.wikipedia.org/wiki/Interfaz_gráfica_de_usuario) o de bajo nivel, +entonces solo estará disponible en el proceso principal. Necesitas familiarizarte +con el concepto de [scripts para proceso principal vs scripts para proceso renderer] +(../tutorial/quick-start.md#the-main-process) para ser capaz de usar esos módulos. + +El script del proceso principal es como un script normal de Node.js: + +```javascript +var app = require('app'); +var BrowserWindow = require('browser-window'); + +var window = null; + +app.on('ready', function() { + window = new BrowserWindow({width: 800, height: 600}); + window.loadUrl('https://github.com'); +}); +``` + +El proceso renderer no es diferente de una página web normal, excepto por la +capacidad extra de utilizar módulos de node: + +```html + + + + + + +``` + +Para ejecutar tu aplicación, lee [Ejecutar la aplicación](../tutorial/quick-start.md#run-your-app). \ No newline at end of file diff --git a/docs-translations/es/styleguide.md b/docs-translations/es/styleguide.md new file mode 100644 index 000000000000..2e8e7c6f4a9e --- /dev/null +++ b/docs-translations/es/styleguide.md @@ -0,0 +1,100 @@ +# Gúia de estilo de Electron + +Encuentra el apartado correcto para cada tarea: [leer la documentación de Electron](#reading-electron-documentation) +o [escribir documentación para Electron](#writing-electron-documentation). + +## Escribir Documentación para Electron + +Estas son las maneras en las que construimos la documentación de Electron. + +- Máximo un título `h1` por página. +- Utilizar `bash` en lugar de `cmd` en los bloques de código (por el resaltado + de sintaxis). +- Los títulos `h1` en el documento deben corresponder al nombre del objeto + (ej. `browser-window` → `BrowserWindow`). + - Archivos separados por guiones, mas sin embargo, es correcto. +- No subtítulos seguidos por otros subtítulos, añadir por lo menos un enunciado + de descripción. +- Métodos de cabecera son delimitados con apóstrofes: `codigo`. +- Cabeceras de Eventos son delimitados con 'comillas' simples. +- No generar listas de mas de dos niveles (debido al renderizador de Markdown + desafortunadamente). +- Agregar títulos de sección: Eventos, Métodos de Clases y Métodos de Instancia. +- Utilizar 'deberá' en lugar de 'debería' al describir resultados. +- Eventos y Métodos son cabeceras `h3`. +- Argumentos opcionales escritos como `function (required[, optional])`. +- Argumentos opcionales son denotados cuando se llaman en listas. +- Delimitador de línea de 80-columnas. +- Métodos específicos de Plataformas son denotados en italicas seguidas por la cabecera del método. + - ```### `method(foo, bar)` _OS X_``` +- Preferir 'en el ___ proceso' en lugar de 'sobre el' + +### Traducciones de la Documentación + +Traducciones de documentos de Electron se encuentran dentro del folder +`docs-translations`. + +Para agregar otro set (o un set parcial): + +- Crear un subdirectorio nombrado igual a la abreviación del lenguaje. +- Dentro de ese subdirectorio, duplicar el directorio de `docs`, manteniendo los + mismos nombres de directorios y archivos. +- Traducir los archivos. +- Actualizar el `README.md` dentro del subdirectorio del lenguaje apuntando a + los archivos que has traducido. +- Agregar un enlace al folder de tu traducción en la sección principal Electron +[README](https://github.com/atom/electron#documentation-translations). + +## Leyendo la Documentación de Electron + +Estos son algunos consejos para entender la syntaxis de la documentación de +Electron. + +### Métodos + +Un ejemplo de la documentación del [método](https://developer.mozilla.org/en-US/docs/Glossary/Method): + +--- + +`methodName(required[, optional]))` + +* `require` String, **required** +* `optional` Integer + +--- + +El nombre del método es seguido por los argumentos que recibe. Argumentos +opcionales son denotados por corchetes rodeados por el argumento opcional y la +coma requerida si el argumento opcional fuera seguido por otro argumento. + +Debajo del método se encuentra mas información detallada de cada uno de los +argumentos. El tipo de argumento es denotado por los tipos comúnes: +[`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) +o un tipo personalizado como el [`webContent`](api/web-content.md) de Electron. + +### Eventos + +Un ejemplo de documentación del [evento](https://developer.mozilla.org/en-US/docs/Web/API/Event): + +--- + +Event: 'wake-up' + +Returns: + +* `time` String + +--- + +El evento es una cadena que es utilizada luego de un método observador `.on`. Si +regresa un valor, el y su tipo son denotados abajo. Si se estaba a la escucha y +respondió a este evento se debería ver así: + +```javascript +Alarm.on('wake-up', function(time) { + console.log(time) +}) +``` diff --git a/docs-translations/es/tutorial/application-distribution.md b/docs-translations/es/tutorial/application-distribution.md index 644da8c3c87b..c957332dd862 100644 --- a/docs-translations/es/tutorial/application-distribution.md +++ b/docs-translations/es/tutorial/application-distribution.md @@ -1,10 +1,11 @@ -# Distribución de aplicaciones +# Distribución de la Aplicación -Para distribuir tu aplicación con Electron, debes nombrar al directorio de tu aplicación -como `app`, y ponerlo bajo el directorio de recursos de Electron (en OSX es `Electron.app/Contents/Resources/`, -en Linux y Windows es `resources/`): +Para distribuir tu aplicación con Electron, el directorio que contiene la +aplicación deberá llamarse `app`, y ser colocado debajo del directorio de +recursos de Electron (en OSX es `Electron.app/Contents/Resources/`, en Linux y +Windows es `resources/`), de esta forma: -En OSX: +En OS X: ```text electron/Electron.app/Contents/Resources/app/ @@ -22,18 +23,19 @@ electron/resources/app └── index.html ``` -Posteriormente ejecutas `Electron.app` (o `electron` en Linux, `electron.exe` en Windows), -y Electron iniciará la aplicación. El directorio `electron` será la distribución que recibirán los usuarios finales. +Luego ejecutar `Electron.app` (o `electron` en Linux, `electron.exe` en Windows), +y Electron será iniciado como tu aplicación. El directorio `electron` será +entonces tu distribución que recibirán los usuarios finales. -## Empaquetando tu aplicación como un archivo +## Empaquetando tu aplicación en un archivo -Además de copiar todos tus archivos fuente para la distribución, también puedes -empaquetar tu aplicación como un archivo [asar](https://github.com/atom/asar) -y de esta forma evitar la exposición del código fuente de tu aplicación a los usuarios. +Además de distribuir tu aplicación al copiar todos los archivos de código fuente, +también puedes empaquetar tu aplicación como un archivo [asar](https://github.com/atom/asar) +y de esta forma evitar exponer del código fuente de tu aplicación a los usuarios. -Para usar un archivo `asar` en reemplazo de la carpeta `app`, debes renombrar -el archivo a `app.asar`, y ponerlo bajo el directorio de recursos de Electron (como arriba), -Electron intentará leer el archivo y ejecutar la aplicación desde él. +Para utilizar un archivo `asar` en reemplazo del directorio `app`, debes de +renombrar el archivo a `app.asar`, y colocarlo por debajo el directorio de recursos +de Electron (ver en seguida), Electron intentará leer el archivo y arrancar desde el. En OS X: @@ -49,30 +51,33 @@ electron/resources/ └── app.asar ``` -Más detalles en [Empaquetamiento de aplicaciones](application-packaging-es.md). +Más detalles en [Empaquetado de Aplicaciones](application-packaging.md). -## Rebranding con binarios descargados +## Redefinición con Binarios Descargados -Luego de empaquetar tu aplicación con Electron, podría ser útil agregar tu marca -antes de realizar la distribución. +Luego de empaquetar tu aplicación en Electron, querrás redefinir Electron antes +de distribuirlo a los usuarios. ### Windows -Puedes renombrar `electron.exe` a cualquier nombre que desees, y editar su ícono y otras informaciones -con herramientas como [rcedit](https://github.com/atom/rcedit) o [ResEdit](http://www.resedit.net). +Puedes renombrar `electron.exe` a cualquier nombre que desees, y editar su ícono +y otra información con herramientas como [rcedit](https://github.com/atom/rcedit) +o [ResEdit](http://www.resedit.net). -### OS X +### OSX -Puedes renombrar `Electron.app` a cualquier nombre que desees. También debes modificar los campos -`CFBundleDisplayName`, `CFBundleIdentifier` y `CFBundleName` en los siguientes archivos: +Puedes renombrar `Electron.app` a cualquier nombre que desees, y tendrás que +renombrar los campos `CFBundleDisplayName`, `CFBundleIdentifier` y `CFBundleName` +en los siguientes archivos: * `Electron.app/Contents/Info.plist` * `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` -También puedes renombrar el helper de la aplicación para evitar que aparezca como `Electron Helper` -en el Monitor de Actividades. +También puedes renombrar el helper de la aplicación para evitar que aparezca +como `Electron Helper` en el Monitor de Actividades. Pero asegurate de renombrar +el nombre de archivo del ejecutable. -La estructura de una aplicación renombrada sería así: +La estructura de una aplicación renombrada será: ``` MyApp.app/Contents @@ -98,17 +103,19 @@ MyApp.app/Contents Puedes renombrar el ejectuable `electron` a cualquier nombre que desees. -## Rebranding desde el código fuente de Electron +## Redefinición mediante la recompilación de Electron desde el código fuente -También es posible agregar tu marca a Electron mediante un build personalizado. -Para realizar esto debes modificar el archivo `atom.gyp`. +También es posible redefinir Electron cambiando el nombre del producto y +compilandolo desde sus fuentes. Para realizar esto necesitas modificar el +archivo `atom.gyp` y realizar una compilación desde cero. ### grunt-build-atom-shell -La modificación del código de Electron para agregar tu marca puede resultar complicada, una tarea Grunt -se ha creado para manejar esto de forma automatizada: - +La modificación a mano del código de Electron y su compilación puede resultar +complicada, por lo cual se ha generado una tarea Grunt para manejar esto de +forma automaticamente: [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). -Esta tarea se encargará de modificar el archivo `.gyp`, compilar el código -y reconstruir los módulos nativos de la aplicación para que coincidan con el nuevo nombre. +Esta tarea se encargará de modificar el archivo `.gyp`, compilar el código desde +las fuentes, y luego reconstruir los módulos nativos de la aplicación para que +coincidan con el nuevo nombre del ejecutable. diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md new file mode 100644 index 000000000000..2fa04368ec36 --- /dev/null +++ b/docs-translations/ko-KR/api/app.md @@ -0,0 +1,342 @@ +# app + +앱 모듈은 어플리케이션의 생명주기(?) 제어를 책임집니다. + +밑의 예제는 마지막 윈도우가 종료되었을 때, 어떻게 어플리케이션을 종료하는지 설명합니다. + +```javascript +var app = require('app'); +app.on('window-all-closed', function() { + app.quit(); +}); +``` + +## Events + +앱 객체는 밑의 이벤트들을 발현(?)시킵니다. + +### Event: 'will-finish-launching' + +'will-finish-launching' 이벤트는 어플리케이션이 기본적인 시동준비(?)를 마치면 발현(?)됩니다. + 윈도우 운영체제와 리눅스 운영체제 안에서, 'will-finish-launching' 이벤트는 'ready' 이벤트와 동일합니다. +OS X 운영체제 안에서는, 이 이벤트는 'NSApplication'의 'applicationWillFinishLaunching' 알림으로 표현됩니다. +유저는 대개 'open-file'과 'open-url' 이벤트를 위한 listeners을 세팅합니다. +그리고, crash reporter와 auto updater를 시작합니다. + +대부분의 경우, 유저는 모든 것을 'ready' 이벤트 handler로 해결합니다. + +### Event: 'ready' + +Electron이 초기화를 끝냈을 때, 이벤트가 발현합니다. + +### Event: 'window-all-closed' + +모든 윈도우창이 종료되었을 때, 이벤트가 발현합니다. + +이 이벤트는 어플리케이션이 정상 종료되지 않았을 때만 발현됩니다. +만약 유저가 'Cmd + Q' 또는 개발자가 'app.quit()'를 호출했다면, Electron은 먼저 모든 윈도우창 종료를 시도합니다. +그 다음에, 'will-quit' 이벤트를 발현시킵니다. +그리고, 'will-quit'가 발현된 경우에는 'window-all-closed' 이벤트는 발현되지 않습니다. + +### Event: 'before-quit' + +Returns: + +* `event` Event + +어플리케이션이 어플리케이션의 윈도우 종료를 시작하기 전에, 발현됩니다. +'event.preventDefault()' 호출은 어플리케이션의 강제종료 행위를 방지합니다. + +### Event: 'will-quit' + +Returns: + +* `event` Event + +모든 윈도우창이 종료되고 어플리케이션이 종료하고자 할 때, 이벤트가 발현됩니다. +'event.preventDefault()'의 호출은 어플리케이션 종료를 방지합니다. +'will-quit' 이벤트와 'window-all-closed' 이벤트와의 차이점을 확인하려면, +'window-all-close' 이벤트의 설명을 참조합시다. + +### Event: 'quit' + +어플리케이션이 종료될 때, 발현됩니다. + +### Event: 'open-file' + +Returns: + +* `event` Event +* `path` String + +어플리케이션을 이용하여 파일을 열고자 할 때, 발현됩니다. + +'open-file' 이벤트는 보통 어플리케이션이 열려 있을 때와, +파일을 열기 위해 OS가 어플리케이션을 재사용할 때 발현됩니다. +'open-file'은 파일이 dock에 추가될 때와 어플리케이션이 실행하기 전에도 발현됩니다. +위의 케이스를 처리하기 위해서는, 'ready' 이벤트가 발현되기도 전에, 어플리케이션 시작 초기 시 +'open-file' 이벤트에 linsten을 걸어 놨는지 반드시 확인해야 합니다. + +이 이벤트를 처리하기 위한다면, 유저는 'even.preventDefault()'를 호출해야 합니다. + +### Event: 'open-url' + +Returns: + +* `event` Event +* `url` String + +유저가 어플리케이션을 이용하여 URL을 열고자 할 경우, 발현됩니다. +어플리케이션을 통해 열기 위해서는 URL 구조가 반드시 등록되어 있어야 합니다. +이 이벤트를 처리하기 위해선, 유저가 'event.preventDefault()'을 호출해야 합니다. + +### Event: 'activate' _OS X_ + +Returns: + +* `event` Event +* `hasVisibleWindows` Bool + +어플리케이션이 활성화 되었을 때 발현됩니다. +(어플리케이션은 dock 아이콘을 click했을 때 주로 활성화됩니다.) + +### Event: 'browser-window-blur' + +Returns: + +* `event` Event +* `window` BrowserWindow + +[browserWindow](browser-window.md)가 흐려졌을 때, 호출됩니다. + +### Event: 'browser-window-focus' + +Returns: + +* `event` Event +* `window` BrowserWindow + +[browserWindow](browser-window.md)을 포커싱했을 때, 호출됩니다. +(포커싱이란? 클릭 또는 활성화했을 때를 의미) + +### Event: 'browser-window-created' + +Returns: + +* `event` Event +* `window` BrowserWindow + +새로운 [browserWindow](browser-window.md)가 생성될 때 발현됩니다. + +### Event: 'select-certificate' + +유저인증이 요청되었을 때 발현됩니다. + +Returns: + +* `event` Event +* `webContents` [WebContents](browser-window.md#class-webcontents) +* `url` String +* `certificateList` [Objects] + * `data` PEM encoded data + * `issuerName` Issuer's Common Name +* `callback` Function + +```javascript +app.on('select-certificate', function(event, host, url, list, callback) { + event.preventDefault(); + callback(list[0]); +}) +``` + +'url' 유저인증 요청의 탐색 항목에 대응합니다. +그리고, 'callback' 는 리스트로 필터링된 항목과 함께 호출될 필요가 있습니다. + +'event.preventDefault()' 호출은 기록소로부터 처음인증된 정보를 사용하는 +어플리케이션을 막습니다. + +### Event: 'gpu-process-crashed' + +GPU가 충돌을 일으켰을 때, 발현됩니다. + +## Methods + +'app' 객체는 밑의 함수를 포함하고 있습니다: + +**Note:** 어떤 함수들은 표시된 특정한 운영체제에서만 사용가능합니다. + +### `app.quit()` + +모든 윈도우창 종료를 시도합니다. 'before-quit' 이벤트가 먼저 발현됩니다. +모든 윈도우창이 성공적으로 종료되었다면, 'will-quit' 이벤트가 발현하고, +디폴트설정으로 어플리케이션이 종료됩니다. + +이 함수는 모든 'beforeunload'과 'unload' 이벤트 처리기가 제대로 실행되었음을 보장합니다. +(즉, 'beforeunload'와 'unload'가 정상 실행되었을 때, 실행가능합니다.) + +'beforeunload' 이벤트 처리기가 'false'를 반환하였을 경우, 윈도우 창 종료가 취소 될 수 있습니다. + + +### `app.getAppPath()` + +현재 어플리케이션의 디렉토리를 반환합니다. + +### `app.getPath(name)` + +* `name` String + +특정한 디렉토리의 경로나 'name' 파일의 경로를 찾아 반환합니다. +실패할 경우, 'Error'를 반환합니다. + +유저는 다음과 같은 이름으로 경로를 요쳥할 수 있습니다: + +* `home` = 유저의 홈 디렉토리. +* `appData` = 유저의 어플리케이션 데이터 디렉토리, 디폴트설정으로: + * `%APPDATA%` = on Windows + * `$XDG_CONFIG_HOME` 또는 `~/.config` = on Linux + * `~/Library/Application Support` = on OS X +* `userData` = 유저 app의 설정파일을 저장하는 디렉토리, +디폴트설정으로 'appData' 디렉토리에 유저 app의 이름을 추가한 형식. +* `temp` = 임시 디렉토리. +* `userDesktop` = 현재 로그인한 유저의 데스트탑 디렉토리. +* `exe` = 현재 실행가능한 파일. +* `module` = `libchromiumcontent` 라이브러리. + +### `app.setPath(name, path)` + +* `name` String +* `path` String + +특정한 디렉토리나 파일이름이 'name'인 'path'를 재정의합니다. +만약 지정된 디렉토리의 경로가 존재하지 않는다면, 디렉토리가 새로 생성됩니다. +실패시, 'Error'를 반환합니다. + +유저는 'app.getPath'에 정의되어 있는 'name' 경로만 재정의할 수 있습니다. + +디폴트설정으로, 웹페이지의 쿠키와 캐시는 'userData' 디렉토리 밑에 저장됩니다. + +만약 유저가 이 위치를 변경하고자 한다면, 'app' 모듈의 'ready' 이벤트가 발현되기 전, +유저는 반드시 'userData' 경로를 재정의해야 합니다. + +### `app.getVersion()` + +로드된 어플리케이션의 버전을 반환합니다. + +만약 'package.json' 파일에서 어플리케이션의 버전을 찾지 못한다면, +현재 번들 또는 실행 파일의 버전이 반환됩니다. + +### `app.getName()` + +응용프로그램(=어플리케이션)의 'package.json' 파일에 있는 +현재 응용프로그램의 이름을 반환합니다. + +NPM 모듈 스펙에 따라, 대부분 'package.json'의 'name' 필드는 소문자 이름입니다. +유저는 'productName'의 필드를 지정해야 합니다. +'productName'는 응용프로그램의 대문자 이름입니다. +'productName'는 Electron에서 선호하는 'name' 입니다. + +### `app.getLocale()` + +현재 응용프로그램의 locale을 반환합니다. + +### `app.resolveProxy(url, callback)` + +* `url` URL +* `callback` Function + +'url'을 위해 프록시 정보를 해석합니다. +'callback'은 'callback(proxy)' 요청이 수행될 때, +호출됩니다. + +### `app.addRecentDocument(path)` + +* `path` String + +최근 문서 목록에 'path'를 추가합니다. + +목록은 운영체제에 의해 관리됩니다. +Windows 운영체제에서는, 작업표시줄에서 참조할 수 있습니다. +OS X 운영체제에서는, dock 메뉴에서 참조할 수 있습니다. + +### `app.clearRecentDocuments()` + +최근 문서 목록을 모두 지웁니다. + +### `app.setUserTasks(tasks)` _Windows_ + +* `tasks` Array - 'Task' 객체의 배열 + +Windows 운영체제에서 JumpList의 [Tasks][tasks] 카테고리로 'tasks'를 추가합니다. + +'tasks'는 밑의 형식을 따르는 'Task' 객체의 배열입니다: + +`Task` Object +* `program` String - 프로그램을 실행할 경로, 대부분 유저는 현재 프로그램을 여는 'process.execPath'를 지정합니다. +* `arguments` String - 'program'이 실행될 때의 명령문 인자. +* `title` String - JumpList에 표시할 문장. +* `description` String - 이 task 객체에 대한 설명. +* `iconPath` String - 아이콘을 포함한 임의의 리소스 파일이며, JumpList에 표시될 아이콘의 절대 경로. +유저는 대부분 프로그램의 아이콘을 표시하기 위해 'process.execPath'를 지정합니다. +* `iconIndex` Integer - 아이콘 파일안의 아이콘 색인(index). 만약, 아이콘 파일 안에 두 개 이상의 아이콘이 있을 경우, + 아이콘을 특정하기 위해 이 값을 설정합니다. 단, 하나의 아이콘만 있을 경우는 0 값을 가집니다. + +### `app.commandLine.appendSwitch(switch[, value])` + +Append a switch (with optional `value`) to Chromium's command line. +Chromium의 명령문에 (선택적으로, 'value'와 함께) switch를 추가합니다. + +**Note:** 이 함수는 'process.argv'에 영향을 주지 않습니다. +그리고, 보통 이 함수는 개발자들이 하드웨어 수준의 Chrominum의 행동을 제어하기 위해 주로 사용됩니다. + +### `app.commandLine.appendArgument(value)` + +Chromium의 명령문에 인자를 추가합니다. 인자는 올바르게 인용될 것입니다. + +**Note:** 'process.argv'에 영향을 주지는 않습니다. + +### `app.dock.bounce([type])` _OS X_ + +* `type` String (optional) - 'critical'이나 'informational'. 디폴트 설정은 'informational' + +'critical'이 input으로 전달되면, dock 아이콘은 응용프로그램이 활성화되거나, 요청이 취소될 때까지 +계속 bounce합니다. + +'informational'이 input으로 전달되면, dock 아이콘은 1초만 bounce합니다. +그러나, 응용프로그램이 활성화되거나 요청이 취소될 때까지 요청은 계속 활성화되어 있습니다. + +요청을 대표하는 ID를 반환합니다. + +### `app.dock.cancelBounce(id)` _OS X_ + +* `id` Integer + +'id'의 반송을 취소합니다. + + +### `app.dock.setBadge(text)` _OS X_ + +* `text` String + +dock의 badge 구역에 표현될 문장을 설정합니다. + +### `app.dock.getBadge()` _OS X_ + +dock의 badge 라인을 반환합니다. + + +### `app.dock.hide()` _OS X_ + +dock 아이콘을 숨깁니다. + +### `app.dock.show()` _OS X_ + +dock 아이콘을 보여줍니다. + +### `app.dock.setMenu(menu)` _OS X_ + +* `menu` Menu + +어플리케이션의 [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 diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md index e60d9505a24a..74923a411c5d 100644 --- a/docs-translations/pt-BR/README.md +++ b/docs-translations/pt-BR/README.md @@ -10,9 +10,9 @@ ## Tutoriais -* [Introdução](../../docs/tutorial/quick-start.md) -* [A integração com o ambiente de desenvolvimento](../../docs/tutorial/desktop-environment-integration.md) -* [Evento de detecção on-line/off-line](../../docs/tutorial/online-offline-events.md) +* [Introdução](tutorial/quick-start.md) +* [A integração com o ambiente de desenvolvimento](tutorial/desktop-environment-integration.md) +* [Evento de detecção on-line/off-line](tutorial/online-offline-events.md) ## API - Referencias @@ -68,4 +68,4 @@ Módulos de ambos os processos: * [Instrução de build (Mac)](../../docs/development/build-instructions-osx.md) * [Instrução de build (Windows)](../../docs/development/build-instructions-windows.md) * [Instrução de build (Linux)](../../docs/development/build-instructions-linux.md) -* [Configurando um symbol server no debugger](../../docs/development/setting-up-symbol-server.md) \ No newline at end of file +* [Configurando um symbol server no debugger](../../docs/development/setting-up-symbol-server.md) diff --git a/docs-translations/pt-BR/tutorial/desktop-environment-integration.md b/docs-translations/pt-BR/tutorial/desktop-environment-integration.md new file mode 100644 index 000000000000..20a78d32d537 --- /dev/null +++ b/docs-translations/pt-BR/tutorial/desktop-environment-integration.md @@ -0,0 +1,260 @@ +# Integração com o ambiente desktop + +Diferentes sistemas operacionais possuem diferentes formas de integrar +aplicacões desktop em seus ambientes. Por exemplo, no Windows, as aplicações podem +inserir atalhos no JumpList da barra de tarefas, no Mac, aplicações podem implementar um +menu customizado na dock. + +Este guia explica como integrar suas aplicações no ambiente desktop com a API +do Electron. + +## Documentos Recentes (Windows & OS X) + +O Windows e o OS X disponibilizam um acesso fácil para a lista de arquivos +abertos recentemente pela aplicação através do JumpList ou Dock Menu respectivamente. + +__JumpList:__ + +![JumpList Recent Files](http://i.msdn.microsoft.com/dynimg/IC420538.png) + +__Dock menu da Aplicação:__ + + + +Para adicionar um arquivo para os documentos recentes, você pode usar a API +[app.addRecentDocument][addrecentdocument]: + +```javascript +var app = require('app'); +app.addRecentDocument('/Users/USERNAME/Desktop/work.type'); +``` + +E você pode usar a API [app.clearRecentDocuments][clearrecentdocuments] para +limpar a lista de documentos recentes. + +```javascript +app.clearRecentDocuments(); +``` + +### Notas para Windows + +A fim de ser possível usar estas funcionalidades no Windows, sua aplicação deve +estar registrada como um handler daquele tipo de documento, caso contrário, o +arquivo não será exibido no JumpList mesmo depois de você ter adicionado isto. +Você pode encontrar qualquer coisa sobre o registro da aplicacão em +[Application Registration][app-registration]. + +Quando um usuário clica em um arquivo na JumpList, uma nova instância da sua aplicacão +deve ser iniciada com o caminho do arquivo adicionado como um argumento de +linha de comando. + +### Notas para OS X + +Quando um arquivo for requisitado pelo menu de documentos recentes, o evento `open-file` +do módulo `app` irá ser emitido. + +## Dock Menu customizado (OS X) + +OS X permite que desenvolvedores especifiquem um menu customizado para a dock, +que normalmente contém alguns atalhos para as funcionalidades mais utilizadas +da sua aplicação. + +__Dock menu do Terminal.app:__ + + + +Para criar seu Dock Menu customizado, você pode usar a API `app.dock.setMenu`, +ela está disponível apenas no OS X: + +```javascript +var app = require('app'); +var Menu = require('menu'); +var dockMenu = Menu.buildFromTemplate([ + { label: 'New Window', click: function() { console.log('New Window'); } }, + { label: 'New Window with Settings', submenu: [ + { label: 'Basic' }, + { label: 'Pro'} + ]}, + { label: 'New Command...'} +]); +app.dock.setMenu(dockMenu); +``` + +## Tarefas do Usuário (Windows) + +No Windows você pode especificar ações customizadas na categoria `Tarefas` do JumpList, +esse texto foi copiado do MSDN: + +> Applications define tasks based on both the program's features and the key +> things a user is expected to do with them. Tasks should be context-free, in +> that the application does not need to be running for them to work. They +> should also be the statistically most common actions that a normal user would +> perform in an application, such as compose an email message or open the +> calendar in a mail program, create a new document in a word processor, launch +> an application in a certain mode, or launch one of its subcommands. An +> application should not clutter the menu with advanced features that standard +> users won't need or one-time actions such as registration. Do not use tasks +> for promotional items such as upgrades or special offers. +> +> It is strongly recommended that the task list be static. It should remain the +> same regardless of the state or status of the application. While it is +> possible to vary the list dynamically, you should consider that this could +> confuse the user who does not expect that portion of the destination list to +> change. + +__Tarefas do Internet Explorer:__ + +![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png) + +Ao contrário do Menu Dock no OS X que é um verdadeiro menu, tarefas do usuário no Windows +funcionam como atalhos, de uma forma que quando o usuário clica em uma tarefa, um programa +deve ser executado com os argumentos especificados. + +Para setar tarefas do usuário para sua aplicação, você pode usar a API +[app.setUserTasks][setusertaskstasks]: + +```javascript +var app = require('app'); +app.setUserTasks([ + { + program: process.execPath, + arguments: '--new-window', + iconPath: process.execPath, + iconIndex: 0, + title: 'New Window', + description: 'Create a new window' + } +]); +``` + +Para limpar sua lista de tarefas, apenas chame `app.setUserTasks` com um +array vazio. + +```javascript +app.setUserTasks([]); +``` + +As tarefas do usuário são exibidas mesmo depois da aplicação ser fechada, +então o ícone e o caminho do programa especificado pela tarefa deve existir +até sua aplicação ser desinstalada. + +## Miniaturas na Barra de Ferramentas + +No Windows você pode adicionar uma miniatura na barra de ferramentas com botões +específicos para a janela e barra de tarefas para aplicação. Isso provê ao usuário +uma forma de acessar um comando específico para janela sem ser necessário restaurar +ou ativar a janela. + +Isto é ilustrado no MSDN: + +> This toolbar is simply the familiar standard toolbar common control. It has a +> maximum of seven buttons. Each button's ID, image, tooltip, and state are defined +> in a structure, which is then passed to the taskbar. The application can show, +> enable, disable, or hide buttons from the thumbnail toolbar as required by its +> current state. +> +> For example, Windows Media Player might offer standard media transport controls +> such as play, pause, mute, and stop. + +__Miniaturas da barra de tarefas do Windows Media Player:__ + +![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png) + +Você pode usar [BrowserWindow.setThumbarButtons][setthumbarbuttons] para criar +miniaturas na barra de ferramentas para sua aplicação. + +``` +var BrowserWindow = require('browser-window'); +var path = require('path'); +var win = new BrowserWindow({ + width: 800, + height: 600 +}); +win.setThumbarButtons([ + { + tooltip: "button1", + icon: path.join(__dirname, 'button1.png'), + click: function() { console.log("button2 clicked"); } + }, + { + tooltip: "button2", + icon: path.join(__dirname, 'button2.png'), + flags:['enabled', 'dismissonclick'], + click: function() { console.log("button2 clicked."); } + } +]); +``` + +Para limpar os botões na miniatura da barra de ferramentas, apenas chame +`BrowserWindow.setThumbarButtons` com um array vazio. + +```javascript +win.setThumbarButtons([]); +``` + +## Unity Launcher Shortcuts (Linux) + +No Unity, você pode adicionar entradas customizadas para estes lançadores modificando +o arquivo `.desktop`, veja [Adding Shortcuts to a Launcher][unity-launcher]. + +__Launcher shortcuts do Audacious:__ + +![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png) + +## Barra de Progresso na Barra de Tarefas (Windows & Unity) + +No Windows o botão na barra de tarefas pode ser usado para exibir uma barra de progresso. +Isto permite que a janela exiba informação sobre o progresso de algum processo sem +a necessidade do usuário mudar de janela. + +A Unity DE também tem uma funcionalidade parecida que permite especificar uma barra +de progresso no ícone do lançador. + +__Barra de Progresso no botão da barra de tarefas:__ + +![Barra de Progresso na Barra de Tarefas](https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png) + +__Barra de progresso no Unity launcher:__ + +![Unity Launcher](https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png) + +Para adicionar uma barra de progresso para uma janela, você pode ver a API: +[BrowserWindow.setProgressBar][setprogressbar]: + +```javascript +var window = new BrowserWindow({...}); +window.setProgressBar(0.5); +``` + +## Representação do arquivo na janela (OS X) + +No OS X, uma janela pode possuir a representação de um arquivo na barra de título, +permitindo que ao usuário acionar um Command-Click ou Control-Click sobre o título da janela, +uma pop-up de navegação entre arquivos é exibida. + +Você também pode inserir um estado de edição na janela para que o ícone do arquivo +possa indicar se o documento nesta janela foi modificado. + +__Menu popup da representação de arquivo:__ + + + +Para inserir o arquivo de representacão da janela, você pode usar as API +[BrowserWindow.setRepresentedFilename][setrepresentedfilename] e +[BrowserWindow.setDocumentEdited][setdocumentedited]: + +```javascript +var window = new BrowserWindow({...}); +window.setRepresentedFilename('/etc/passwd'); +window.setDocumentEdited(true); +``` + +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks +[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename +[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx +[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher +[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons diff --git a/docs-translations/pt-BR/tutorial/online-offline-events.md b/docs-translations/pt-BR/tutorial/online-offline-events.md new file mode 100644 index 000000000000..294a62e7a81c --- /dev/null +++ b/docs-translations/pt-BR/tutorial/online-offline-events.md @@ -0,0 +1,83 @@ +# Online/Offline Event Detection + +Os eventos de detecão Online e Offile podem ser implementados no processo +de renderização utilizando a API padrão do HTML, como é mostrado no exemplo +a seguir. + +_main.js_ + +```javascript +var app = require('app'); +var BrowserWindow = require('browser-window'); +var onlineStatusWindow; + +app.on('ready', function() { + onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); + onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); +}); +``` + +_online-status.html_ + +```html + + + + + + +``` + +Pode haver casos onde você também deseja responder a estes eventos no processo principal. +Mas o processo principal não consegue detectar esses eventos diretamente, pois não possui +um objeto `navigator`. Utilizando a ferramentas para comunicação entre processos, os eventos +podem ser direcionados para o processo principal e manipulados quando necessário. Você +pode ver isto no exemplo abaixo. + +_main.js_ + +```javascript +var app = require('app'); +var ipc = require('ipc'); +var BrowserWindow = require('browser-window'); +var onlineStatusWindow; + +app.on('ready', function() { + onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); + onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); +}); + +ipc.on('online-status-changed', function(event, status) { + console.log(status); +}); +``` + +_online-status.html_ + +```html + + + + + + +``` diff --git a/docs-translations/pt-BR/tutorial/quick-start.md b/docs-translations/pt-BR/tutorial/quick-start.md new file mode 100644 index 000000000000..3ec71961a92b --- /dev/null +++ b/docs-translations/pt-BR/tutorial/quick-start.md @@ -0,0 +1,192 @@ +# Introdução + +Electron permite criar aplicações desktop com puro JavaScript através de +um runtime com APIs ricas e nativas. Você pode ver isso como uma variação do +runtime do io.js que é focado em aplicações desktop em vez de web servers. + +Isso não significa que o Electron é uma ligação em JavaScript para blibliotécas +de interface gráfica (GUI). Em vez disso, Electron usa páginas web como +interface gráfica, então você pode ver isso também como um navegador Chromium +mínimo, controlado por JavaScript. + +### Processo Principal + +No Electron, o processo que executa o script principal (main) do `package.json` +é chamado __processo principal__. O script que roda no processo principal pode +mostrar uma GUI criando páginas web. + +### Processo Renderizador + +Desde que o Electron usa o Chromium para mostrar as páginas web, a arquitetura +multi-processo do Chromium também é usada. Cada página web no Electron roda em +seu próprio processo, o que é chamado de __processo renderizador__. + +Em navegadores comuns, as páginas web normalmente rodam em um ambiente em sandbox +e não tem permissão de acesso para recursos nativos. Usuários Electron, entretanto, +tem o poder de usar as APIs do io.js nas páginas web, permitindo interações de baixo +nível no sistema operacional. + +### Diferenças Entre o Processo Principal e o Processo Renderizador + +O processo principal cria as páginas web criando instâncias de `BrowserWindow`. +Cada instância de `BrowserWindow` roda a página web em seu próprio processo renderizador. +Quando uma instância de `BrowserWindow` é destruída, o processo renderizador +correspondente também é finalizado. + +O processo principal gerência todas as páginas web de seus processos renderizadores +correspondentes. Cada processo renderizador é isolado e toma conta de sua +respectiva página web. + +Nas páginas web, chamar APIs nativas relacionadas à GUI não é permitido porque +gerênciar recursos de GUI em páginas web é muito perigoso e torna fácil o vazamento de +recursos. Se você quer realizar operações com GUI em páginas web, o processo +renderizador da página web deve se comunicar com o processo principal para requisitar +que o processo principal realize estas operações. + +No Electron, nós fornecemos o módulo [ipc](../../../docs/api/ipc-renderer.md) para +comunicação entre o processo principal e o processo renderizador. Que é também um +módulo [remoto](../../../docs/api/remote.md) para comunicação RPC. + +## Crie seu Primeiro App Electron + +Geralmente, um app Electron é estruturado assim: + +```text +your-app/ +├── package.json +├── main.js +└── index.html +``` + +O formato de `package.json` é exatamente o mesmo que os dos módulos do Node, e +e o script especificado pelo campo `main` é o script de inicialização do seu app, +que irá executar o processo principal. Um exemplo do seu `package.json` deve parecer +com isso: + +```json +{ + "name" : "your-app", + "version" : "0.1.0", + "main" : "main.js" +} +``` + +__Nota__: Se o campo `main` não estiver presente no `package.jso`, o Electron irá +tentar carregar um `index.js` + +O `main.js` deve criar as janelas e os manipuladores de eventos do sistema, um típico +exemplo: + +```javascript +var app = require('app'); // Módulo para controlar o ciclo de vida do app. +var BrowserWindow = require('browser-window'); // Módulo para criar uma janela nativa do browser. + +// Relate falhas para nossos servidores. +require('crash-reporter').start(); + +// Mantenha uma referência global para o objeto window, se você não o fizer, +// a janela será fechada automaticamente quando o objeto JavaScript for +// coletado pelo garbage collector. +var mainWindow = null; + +// Sair quando todas as janelas estiverem fechadas. +app.on('window-all-closed', function() { + // No OS X é comum para as aplicações na barra de menu + // continuarem ativas até que o usuário saia explicitamente + // com Cmd + Q + if (process.platform != 'darwin') { + app.quit(); + } +}); + +// Esse método irá ser chamado quando o Electron finalizar +// a inicialização e estiver pronto para criar janelas do browser. +app.on('ready', function() { + // Criar a janela do navegador. + mainWindow = new BrowserWindow({width: 800, height: 600}); + + // e carrega o index.html do app. + mainWindow.loadUrl('file://' + __dirname + '/index.html'); + + // Abre os DevTools. + mainWindow.openDevTools(); + + // Emitido quando a janela é fechada. + mainWindow.on('closed', function() { + // Desfaz a referência para o objeto window, normalmente você deverá + // guardar as janelas em um array se seu app suportar várias janelas, + // essa é a hora que você deverá deletar o elemento correspondente. + mainWindow = null; + }); +}); +``` + +Finalmente o `index.html` é a página web que você quer mostrar: + +```html + + + + + Hello World! + + +

Hello World!

+ Nós estamos usando io.js + e Electron . + + +``` + +## Execute seu App + +Uma vez que você criou seus arquivos `main.js`, `index.html, e `package.json` iniciais, +você provavelmente vai querer tentar executar seu app localmente para testa-lo a ter +certeza que funciona como você espera. + +### electron-prebuilt + +Se você instalou `electron-prebuilt` globalmente com `npm`, então você irá precisar apenas +rodar o seguinte comando no diretório fonte do seu app: + +```bash +electron . +``` + +Se você o instalou localmente, então execute: + +```bash +./node_modules/.bin/electron . +``` + +### Binário do Electron Baixado Manualmente + +Se você baixou o Electron manualmente, você pode também usar o binário incluído para +executar seu app diretamente. + +#### Windows + +```bash +$ .\electron\electron.exe your-app\ +``` + +#### Linux + +```bash +$ ./electron/electron your-app/ +``` + +#### OS X + +```bash +$ ./Electron.app/Contents/MacOS/Electron your-app/ +``` + +`Electron.app` aqui é uma parte do pacote de lançamento do Electron, você pode baixa-lo +[aqui](https://github.com/atom/electron/releases). + +### Executar como uma distribuição + +Depois de terminar seu app, você pode criar uma distribuição seguindo o guia +[Application Distribution](./application-distribution.md) e então executar o app +empacotado. diff --git a/docs-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index 124d030c46ee..6085cbfb2c65 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -1,5 +1,6 @@ ## 向导 +* [支持平台](tutorial/supported-platforms.md) * [应用部署](tutorial/application-distribution.md) * [应用打包](tutorial/application-packaging.md) * [使用原生模块](tutorial/using-native-node-modules.md) diff --git a/docs-translations/zh-CN/api/app.md b/docs-translations/zh-CN/api/app.md new file mode 100644 index 000000000000..03eb083dfa6e --- /dev/null +++ b/docs-translations/zh-CN/api/app.md @@ -0,0 +1,315 @@ +# app + +`app` 模块是为了控制整个应用的生命周期设计的。 + +下面的这个例子将会展示如何在最后一个窗口被关闭时退出应用: + +```javascript +var app = require('app'); +app.on('window-all-closed', function() { + app.quit(); +}); +``` + +## 事件 + +`app` 对象会触发以下的事件: + +### 事件: 'will-finish-launching' + +当应用程序完成基础的启动的时候被触发。在 Windows 和 Linux 中, +`will-finish-launching` 事件与 `ready` 事件是相同的; 在 OS X 中, +这个时间相当于 `NSApplication` 中的 `applicationWillFinishLaunching` 提示。 +你应该经常在这里为 `open-file` 和 `open-url` 设置监听器,并启动崩溃报告和自动更新。 + +在大多数的情况下,你应该只在 `ready` 事件处理器中完成所有的业务。 + +### 事件: 'ready' + +当 Electron 完成初始化时被触发。 + +### 事件: 'window-all-closed' + +当所有的窗口都被关闭时触发。 + +这个时间仅在应用还没有退出时才能触发。 如果用户按下了 `Cmd + Q`, +或者开发者调用了 `app.quit()` ,Electron 将会先尝试关闭所有的窗口再触发 `will-quit` 事件, +在这种情况下 `window-all-closed` 不会被触发。 + +### 事件: 'before-quit' + +返回: + +* `event` 事件 + +在应用程序开始关闭它的窗口的时候被触发。 +调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 + +### 事件: 'will-quit' + +返回: + +* `event` 事件 + +当所有的窗口已经被关闭,应用即将退出时被触发。 +调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 + +你可以在 `window-all-closed` 事件的描述中看到 `will-quit` 事件 +和 `window-all-closed` 事件的区别。 + +### 事件: 'quit' + +当应用程序正在退出时触发。 + +### 事件: 'open-file' + +返回: + +* `event` 事件 +* `path` 字符串 + +当用户想要在应用中打开一个文件时触发。`open-file` 事件常常在应用已经打开并且系统想要再次使用应用打开文件时被触发。 + `open-file` 也会在一个文件被拖入 dock 且应用还没有运行的时候被触发。 +请确认在应用启动的时候(甚至在 `ready` 事件被触发前)就对 `open-file` 事件进行监听,以处理这种情况。 + +如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 + +### 事件: 'open-url' + +返回: + +* `event` 事件 +* `url` 字符串 + +当用户想要在应用中打开一个url的时候被触发。URL格式必须要提前标识才能被你的应用打开。 + +如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 + +### 事件: 'activate' _OS X_ + +返回: + +* `event` 事件 +* `hasVisibleWindows` 布尔值 + +当应用被激活时触发,常用于点击应用的 dock 图标的时候。 + +### 事件: 'browser-window-blur' + +返回: + +* `event` 事件 +* `window` 浏览器窗口 + +当一个 [浏览器窗口](browser-window.md) 失去焦点的时候触发。 + +### 事件: 'browser-window-focus' + +返回: + +* `event` 事件 +* `window` 浏览器窗口 + +当一个 [浏览器窗口](browser-window.md) 获得焦点的时候触发。 + +### 事件: 'browser-window-created' + +返回: + +* `event` 事件 +* `window` 浏览器窗口 + +当一个 [浏览器窗口](browser-window.md) 被创建的时候触发。 + +### 事件: 'select-certificate' + +当一个客户端认证被请求的时候被触发。 + +返回: + +* `event` 事件 +* `webContents` [web组件](browser-window.md#class-webcontents) +* `url` 字符串 +* `certificateList` 对象 + * `data` PEM 编码数据 + * `issuerName` 发行者的公有名称 +* `callback` 函数 + +```javascript +app.on('select-certificate', function(event, host, url, list, callback) { + event.preventDefault(); + callback(list[0]); +}) +``` + +The `url` corresponds to the navigation entry requesting the client certificate +and `callback` needs to be called with an entry filtered from the list. +Using `event.preventDefault()` prevents the application from using the first +certificate from the store. + +### 事件: 'gpu-process-crashed' + +当GPU进程崩溃时触发。 + +## 方法 + +`app` 对象拥有以下的方法: + +**提示:** 有的方法只能用于特定的操作系统。 + +### `app.quit()` + +试图关掉所有的窗口。`before-quit` 事件将会被最先触发。如果所有的窗口都被成功关闭了, +`will-quit` 事件将会被触发,默认下应用将会被关闭。 + +这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。会存在一个窗口被 `beforeunload` 事件处理器返回 `false` 取消退出的可能性。 + +### `app.getAppPath()` + +返回当前应用所在的文件路径。 + +### `app.getPath(name)` + +* `name` 字符串 + +返回一个与 `name` 参数相关的特殊文件夹或文件路径。当失败时抛出一个 `Error` 。 + +你可以通过名称请求以下的路径: + +* `home` 用户的 home 文件夹。 +* `appData` 所有用户的应用数据文件夹,默认对应: + * `%APPDATA%` Windows 中 + * `$XDG_CONFIG_HOME` or `~/.config` Linux 中 + * `~/Library/Application Support` OS X 中 +* `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称。 +* `cache` 所有用户应用程序缓存的文件夹,默认对应: + * `%APPDATA%` Windows 中 (没有一个通用的缓存位置) + * `$XDG_CACHE_HOME` 或 `~/.cache` Linux 中 + * `~/Library/Caches` OS X 中 +* `userCache` 用于存放应用程序缓存的文件夹,默认是 `cache` 文件夹附加应用的名称。 +* `temp` 临时文件夹。 +* `userDesktop` 当前用户的桌面文件夹。 +* `exe` 当前的可执行文件。 +* `module` `libchromiumcontent` 库。 + +### `app.setPath(name, path)` + +* `name` 字符串 +* `path` 字符串 + +重写 `path` 参数到一个特别的文件夹或者是一个和 `name` 参数有关系的文件。 +如果这个路径指向的文件夹不存在,这个文件夹将会被这个方法创建。 +如果错误则抛出 `Error` 。 + +你只可以指向 `app.getPath` 中定义过 `name` 的路径。You can only override paths of a `name` defined in `app.getPath`. + +默认情况下,网页的 cookie 和缓存都会储存在 `userData` 文件夹。 +如果你想要改变这个位置,你需要在 `app` 模块中的 `ready` 事件被触发之前重写 `userData` 的路径。 + +### `app.getVersion()` + +返回加载应用程序的版本。如果应用程序的 `package.json` 文件中没有写版本号, +将会返回当前包或者可执行文件的版本。 + +### `app.getName()` + +返回当前应用程序的 `package.json` 文件中的名称。 + +通常 `name` 字段是一个短的小写字符串,其命名规则按照 npm 中的模块命名规则。你应该单独列举一个 +`productName` 字段,用于表示你的应用程序的完整名称,这个名称将会被 Electron 优先采用。 + +### `app.getLocale()` + +返回当前应用程序的位置。 + +### `app.resolveProxy(url, callback)` + +* `url` URL +* `callback` 函数 + +为 `url` 解析代理信息。 `callback` 在请求被执行之后将会被 `callback(proxy)` 调用。 + +### `app.addRecentDocument(path)` + +* `path` 字符串 + +为最近访问的文档列表中添加 `path` 。 + +这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过dock 菜单进行访问。 + +### `app.clearRecentDocuments()` + +清除最近访问的文档列表。 + +### `app.setUserTasks(tasks)` _Windows_ + +* `tasks` 由 `Task` 对象构成的数组 + +将 `tasks` 添加到 Windows 中 JumpList 功能的 [Tasks][tasks] 分类中。 + +`tasks` 中的 `Task` 对象格式如下: + +`Task` 对象 +* `program` 字符串 - 执行程序的路径,通常你应该说明当前程序的路径为 `process.execPath` 字段。 +* `arguments` 字符串 - 当 `program` 执行时的命令行参数。 +* `title` 字符串 - JumpList 中显示的标题。 +* `description` 字符串 - 对这个任务的描述。 +* `iconPath` 字符串 - JumpList 中显示的 icon 的绝对路径,可以是一个任意包含一个icon的资源文件。你通常可以通过指明 `process.execPath` 来显示程序中的icon。 +* `iconIndex` 整数 - icon文件中的icon目录。如果一个icon文件包括了两个或多个icon,就需要设置这个值以确定icon。如果一个文件仅包含一个icon,那么这个值为0。 + +### `app.commandLine.appendSwitch(switch[, value])` + +通过可选的参数 `value` 给 Chromium 命令行中添加一个开关。 +Append a switch (with optional `value`) to Chromium's command line. + +**贴士:** 这不会影响 `process.argv` ,这个方法主要被开发者用于控制一些低层级的 Chromium 行为。 + +### `app.commandLine.appendArgument(value)` + +给 Chromium 命令行中加入一个参数。这个参数是当前正在被引用的。 + +**贴士:** 这不会影响 `process.argv`。 + +### `app.dock.bounce([type])` _OS X_ + +* `type` 字符串 (可选的) - 可以是 `critical` 或 `informational`。默认下是 `informational` + +当输入 `critical` 时,dock 中的 icon 将会开始弹跳直到应用被激活或者这个请求被取消。 + +当输入 `informational` 时,dock 中的 icon 只会弹跳一秒钟。 +然而,这个请求仍然会激活,直到应用被激活或者请求被取消。 + +返回一个表示这个请求的 ID。 + +### `app.dock.cancelBounce(id)` _OS X_ + +* `id` 整数 + +取消这个 `id` 对应的请求。 + +### `app.dock.setBadge(text)` _OS X_ + +* `text` 字符串 + +设置 dock 中显示的字符。 + +### `app.dock.getBadge()` _OS X_ + +返回 dock 中显示的字符。 + +### `app.dock.hide()` _OS X_ + +隐藏 dock 中的 icon。 + +### `app.dock.show()` _OS X_ + +显示 dock 中的 icon。 + +### `app.dock.setMenu(menu)` _OS X_ + +* `menu` 菜单 + +设置应用的 [dock 菜单][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 \ No newline at end of file diff --git a/docs-translations/zh-CN/api/ipc-main-process.md b/docs-translations/zh-CN/api/ipc-main-process.md new file mode 100644 index 000000000000..75d5785b2e5f --- /dev/null +++ b/docs-translations/zh-CN/api/ipc-main-process.md @@ -0,0 +1,68 @@ +# ipc (主进程) + +在主进程使用`ipc`模块时,`ipc`负责捕获从渲染进程(网页)发送的同步或者是异步消息. + +## 发送消息 + +主进程也可以向渲染进程发送信息,具体可以看[WebContents.send](web-contents.md#webcontentssendchannel-args). + +- 当发送消息的时候,事件名字为`channel`. +- 回复一个同步消息的时候,你需要使用`event.returnValue` +- 回复一个异步消息的时候,使用`event.sender.send(...)` + +下面是一个主进程和渲染进程的通信例子. + +```javascript +// 在主进程中. +var ipc = require('ipc'); +ipc.on('asynchronous-message', function(event, arg) { + console.log(arg); // 打印 "ping" + event.sender.send('asynchronous-reply', 'pong'); +}); + +ipc.on('synchronous-message', function(event, arg) { + console.log(arg); // 打印 "ping" + event.returnValue = 'pong'; +}); +``` + +```javascript +// 在渲染进程(网页). +var ipc = require('ipc'); +console.log(ipc.sendSync('synchronous-message', 'ping')); // 打印 "pong" + +ipc.on('asynchronous-reply', function(arg) { + console.log(arg); // 打印 "pong" +}); +ipc.send('asynchronous-message', 'ping'); +``` + +## 监听消息 + +`ipc`模块有下列几种方法来监听事件. + +### `ipc.on(channel, callback)` + +* `channel` - 事件名称. +* `callback` - 回调函数. + +当事件发生的时候,会传入`callback` `event`和`arg`参数. + +## IPC 事件 + +传入`callback`的`event`对象含有下列方法. + +### `Event.returnValue` + +在同步消息中,设置这个值将会被返回. + +### `Event.sender` + +返回一个可以发送消息的`WebContents`. + +### `Event.sender.send(channel[.arg1][,arg2][,...])` + +* `channel` - 事件名称. +* `arg` (选用) + +这个可以发送一个可带参数的异步消息回渲染进程. diff --git a/docs-translations/zh-CN/tutorial/application-distribution.md b/docs-translations/zh-CN/tutorial/application-distribution.md new file mode 100644 index 000000000000..c1fddce15ea4 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/application-distribution.md @@ -0,0 +1,109 @@ +# 应用部署 + +为了使用Electron部署你的应用程序,你存放应用程序的文件夹需要叫做 `app` 并且需要放在 Electron 的资源文件夹下(在 OS X 中是指 `Electron.app/Contents/Resources/`,在 Linux 和 Windows 中是指 `resources/`) +就像这样: + +在 OS X 中: + +```text +electron/Electron.app/Contents/Resources/app/ +├── package.json +├── main.js +└── index.html +``` + +在 Windows 和 Linux 中: + +```text +electron/resources/app +├── package.json +├── main.js +└── index.html +``` + +然后运行 `Electron.app` (或者 Linux 中的 `electron`,Windows 中的 `electron.exe`), +接着 Electron 就会以你的应用程序的方式启动。`electron` 文件夹将被部署并可以分发给最终的使用者。 + +## 将你的应用程序打包成一个文件 + +除了通过拷贝所有的资源文件来分发你的应用程序之外,你可以可以通过打包你的应用程序为一个 [asar](https://github.com/atom/asar) 库文件以避免暴露你的源代码。 + +为了使用一个 `asar` 库文件代替 `app` 文件夹,你需要修改这个库文件的名字为 `app.asar` , +然后将其放到 Electron 的资源文件夹下,然后 Electron 就会试图读取这个库文件并从中启动。 +如下所示: + +在 OS X 中: + +```text +electron/Electron.app/Contents/Resources/ +└── app.asar +``` + +在 Windows 和 Linux 中: + +```text +electron/resources/ +└── app.asar +``` + +更多的细节请见 [Application packaging](application-packaging.md). + +## 更换名称与下载二进制文件 + +在使用 Electron 打包你的应用程序之后,你可能需要在分发给用户之前修改打包的名字。 + +### Windows + +你可以将 `electron.exe` 改成任意你喜欢的名字,然后可以使用像 +[rcedit](https://github.com/atom/rcedit) 或者[ResEdit](http://www.resedit.net) +编辑它的icon和其他信息。 + +### OS X + +你可以将 `Electron.app` 改成任意你喜欢的名字,然后你也需要修改这些文件中的 +`CFBundleDisplayName`, `CFBundleIdentifier` 以及 `CFBundleName` 字段。 +这些文件如下: + +* `Electron.app/Contents/Info.plist` +* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` + +你也可以重命名帮助应用程序以避免在应用程序监视器中显示 `Electron Helper`, +但是请确保你已经修改了帮助应用的可执行文件的名字。 + +一个改过名字的应用程序的构造可能是这样的: + +``` +MyApp.app/Contents +├── Info.plist +├── MacOS/ +│   └── MyApp +└── Frameworks/ + ├── MyApp Helper EH.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper EH + ├── MyApp Helper NP.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper NP + └── MyApp Helper.app + ├── Info.plist + └── MacOS/ +    └── MyApp Helper +``` + +### Linux + +你可以将 `electron` 改成任意你喜欢的名字。 + +## 通过重编译源代码来更换名称 + +通过修改产品名称并重编译源代码来更换 Electron 的名称也是可行的。 +你需要修改 `atom.gyp` 文件并彻底重编译一次。 + +### grunt打包脚本 + +手动的检查 Electron 代码并重编译是很复杂晦涩的,因此有一个 Grunt任务可以自动自动的处理 +这些内容 [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). + +这个任务会自动的处理编辑 `.gyp` 文件,从源代码进行编译,然后重编译你的应用程序的本地 Node 模块以匹配这个新的可执行文件的名称。 diff --git a/docs-translations/zh-CN/tutorial/debugging-main-process.md b/docs-translations/zh-CN/tutorial/debugging-main-process.md new file mode 100644 index 000000000000..48f3579394e7 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/debugging-main-process.md @@ -0,0 +1,48 @@ +# 主进程调试 + +浏览器窗口的开发工具仅能调试渲染器的进程脚本(比如web 页面)。为了提供一个可以调试主进程 +的方法,Electron 提供了 `--debug` 和 `--debug-brk` 开关。 + +## 命令行开关 + +使用如下的命令行开关来调试 Electron 的主进程: + +### `--debug=[port]` + +当这个开关用于 Electron 时,它将会监听 V8 引擎中有关 `port` 的调试器协议信息。 +默认的 `port` 是 `5858`。 + +### `--debug-brk=[port]` + +就像 `--debug` 一样,但是会在第一行暂停脚本运行。 + +## 使用 node-inspector 来调试 + +__备注:__ Electron 使用 node v0.11.13 版本,目前对 node-inspector支持的不是特别好, +如果你通过 node-inspector 的 console 来检查 `process` 对象,主进程就会崩溃。 + +### 1. 开始 [node-inspector][node-inspector] 服务 + +```bash +$ node-inspector +``` + +### 2. 打开 Electron 的调试模式 + +你也可以用调试参数来运行 Electron : + +```bash +$ electron --debug=5858 your/app +``` + +或者,在第一行暂停你的脚本: + +```bash +$ electron --debug-brk=5858 your/app +``` + +### 3. 加载调试器界面 + +在 Chrome 中打开 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 + +[node-inspector]: https://github.com/node-inspector/node-inspector diff --git a/docs-translations/zh-CN/tutorial/supported-platforms.md b/docs-translations/zh-CN/tutorial/supported-platforms.md new file mode 100644 index 000000000000..a819e3a0817c --- /dev/null +++ b/docs-translations/zh-CN/tutorial/supported-platforms.md @@ -0,0 +1,27 @@ +# 支持的平台 + +以下的平台是 Electron 目前支持的: + +### OS X + +对于 OS X 系统仅有64位的二进制文档,支持的最低版本是 OS X 10.8。 + +### Windows + +仅支持 Windows 7 及其以后的版本,之前的版本中是不能工作的。 + +对于 Windows 提供 `x86` 和 `amd64` (x64) 版本的二进制文件。需要注意的是 +`ARM` 版本的 Windows 目前尚不支持. + +### Linux + +预编译的 `ia32`(`i686`) 和 `x64`(`amd64`) 版本 Electron 二进制文件都是在 +Ubuntu 12.04 下编译的,`arm` 版的二进制文件是在 ARM v7(硬浮点 ABI 与 +Debian Wheezy 版本的 NEON)下完成的。 + +预编译二进制文件是否能够运行,取决于其中是否包括了编译平台链接的库,所以只有 Ubuntu 12.04 +可以保证正常工作,但是以下的平台也被正事可以运行 Electron的预编译版本: + +* Ubuntu 12.04 及更新 +* Fedora 21 +* Debian 8 diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index adba06e1adcf..c9dfb194529a 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -16,7 +16,7 @@ app.on('ready', function() { // Register a 'ctrl+x' shortcut listener. var ret = globalShortcut.register('ctrl+x', function() { console.log('ctrl+x is pressed'); - }) + }); if (!ret) { console.log('registration failed'); @@ -62,4 +62,4 @@ Unregisters the global shortcut of `accelerator`. ### `globalShortcut.unregisterAll()` -Unregisters all the global shortcuts. +Unregisters all of the global shortcuts. diff --git a/docs/api/protocol.md b/docs/api/protocol.md index 795e4340c7ee..45d4e5146b1f 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -140,7 +140,7 @@ which sends a file as a response. Intercepts `scheme` protocol and uses `handler` as the protocol's new handler which sends a `String` as a response. -## `protocol.interceptBufferProtocol(scheme, handler[, completion])` +### `protocol.interceptBufferProtocol(scheme, handler[, completion])` * `scheme` String * `handler` Function @@ -149,7 +149,7 @@ which sends a `String` as a response. Intercepts `scheme` protocol and uses `handler` as the protocol's new handler which sends a `Buffer` as a response. -## `protocol.interceptHttpProtocol(scheme, handler[, completion])` +### `protocol.interceptHttpProtocol(scheme, handler[, completion])` * `scheme` String * `handler` Function @@ -158,7 +158,7 @@ which sends a `Buffer` as a response. Intercepts `scheme` protocol and uses `handler` as the protocol's new handler which sends a new HTTP request as a response. -## `protocol.uninterceptProtocol(scheme[, completion])` +### `protocol.uninterceptProtocol(scheme[, completion])` * `scheme` String * `completion` Function diff --git a/docs/styleguide.md b/docs/styleguide.md index 77c90467ca93..b471c19fba52 100644 --- a/docs/styleguide.md +++ b/docs/styleguide.md @@ -65,7 +65,11 @@ 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) +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). ### Events diff --git a/docs/tutorial/application-distribution.md b/docs/tutorial/application-distribution.md index 4f1f5202a008..d65bc08ca87f 100644 --- a/docs/tutorial/application-distribution.md +++ b/docs/tutorial/application-distribution.md @@ -35,7 +35,7 @@ exposing your app's source code to users. To use an `asar` archive to replace the `app` folder, you need to rename the archive to `app.asar`, and put it under Electron's resources directory like -below, and Electron will then try read the archive and start from it. +below, and Electron will then try to read the archive and start from it. On OS X: diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 3132edffcc27..78067f3d8a12 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -223,7 +223,7 @@ window.setProgressBar(0.5); ## Represented File of Window (OS X) On OS X a window can set its represented file, so the file's icon can show in -the title bar and when users Command-Click or Control-Click on the tile a path +the title bar and when users Command-Click or Control-Click on the title a path popup will show. You can also set the edited state of a window so that the file icon can indicate diff --git a/docs/tutorial/devtools-extension.md b/docs/tutorial/devtools-extension.md index e9466f14b648..20ba7031d8ad 100644 --- a/docs/tutorial/devtools-extension.md +++ b/docs/tutorial/devtools-extension.md @@ -16,11 +16,13 @@ $ cd /some-directory $ git clone --recursive https://github.com/facebook/react-devtools.git ``` +Follow the instructions in [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) to build the extension. + Then you can load the extension in Electron by opening DevTools in any window, and running the following code in the DevTools console: ```javascript -require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools'); +require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` To unload the extension, you can call the `BrowserWindow.removeDevToolsExtension` diff --git a/package.json b/package.json index a125d13b68ef..a5d56e3a9908 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "asar": "^0.8.0", "coffee-script": "^1.9.2", "coffeelint": "^1.9.4", - "request": "*", + "request": "*" + }, + "optionalDependencies": { "runas": "^3.0.0" }, "private": true, diff --git a/script/bump-version.py b/script/bump-version.py index f910ae3ef95f..3ee0b23df3b8 100755 --- a/script/bump-version.py +++ b/script/bump-version.py @@ -106,10 +106,11 @@ def update_info_plist(version): line = lines[i] if 'CFBundleVersion' in line: lines[i + 1] = ' {0}\n'.format(version) + if 'CFBundleShortVersionString' in line: + lines[i + 1] = ' {0}\n'.format(version) - with open(info_plist, 'w') as f: - f.write(''.join(lines)) - return + with open(info_plist, 'w') as f: + f.write(''.join(lines)) def tag_version(version): diff --git a/script/create-dist.py b/script/create-dist.py index ca7e21642872..5f47b2d358f0 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -8,7 +8,8 @@ import sys import stat from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL, PLATFORM, \ - get_target_arch, get_chromedriver_version + get_target_arch, get_chromedriver_version, \ + get_platform_key from lib.util import scoped_cwd, rm_rf, get_atom_shell_version, make_zip, \ execute, atom_gyp @@ -170,7 +171,8 @@ def create_symbols(): def create_dist_zip(): dist_name = '{0}-{1}-{2}-{3}.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, - PLATFORM, get_target_arch()) + get_platform_key(), + get_target_arch()) zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) with scoped_cwd(DIST_DIR): @@ -182,7 +184,7 @@ def create_dist_zip(): def create_chrome_binary_zip(binary, version): - dist_name = '{0}-{1}-{2}-{3}.zip'.format(binary, version, PLATFORM, + dist_name = '{0}-{1}-{2}-{3}.zip'.format(binary, version, get_platform_key(), get_target_arch()) zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) @@ -198,7 +200,7 @@ def create_chrome_binary_zip(binary, version): def create_symbols_zip(): dist_name = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, - PLATFORM, + get_platform_key(), get_target_arch()) zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) diff --git a/script/lib/config.py b/script/lib/config.py index 68f216785d60..30eedc13e968 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -20,6 +20,13 @@ PLATFORM = { verbose_mode = False +def get_platform_key(): + if os.environ.has_key('MAS_BUILD'): + return 'mas' + else: + return PLATFORM + + def get_target_arch(): try: target_arch_path = os.path.join(__file__, '..', '..', '..', 'vendor', diff --git a/script/update.py b/script/update.py index abb3756ca365..e91e8401cbff 100755 --- a/script/update.py +++ b/script/update.py @@ -55,11 +55,17 @@ def run_gyp(target_arch, component): # Avoid using the old gyp lib in system. env['PYTHONPATH'] = os.path.pathsep.join([gyp_pylib, env.get('PYTHONPATH', '')]) + # Whether to build for Mac App Store. + if os.environ.has_key('MAS_BUILD'): + mas_build = 1 + else: + mas_build = 0 defines = [ '-Dlibchromiumcontent_component={0}'.format(component), '-Dtarget_arch={0}'.format(target_arch), '-Dhost_arch={0}'.format(get_host_arch()), '-Dlibrary=static_library', + '-Dmas_build={0}'.format(mas_build), ] return subprocess.call([python, gyp, '-f', 'ninja', '--depth', '.', 'atom.gyp', '-Icommon.gypi'] + defines, env=env) diff --git a/script/upload.py b/script/upload.py index 6fc421e6b7a2..318bbb594a11 100755 --- a/script/upload.py +++ b/script/upload.py @@ -7,7 +7,8 @@ import subprocess import sys import tempfile -from lib.config import PLATFORM, get_target_arch, get_chromedriver_version +from lib.config import PLATFORM, get_target_arch, get_chromedriver_version, \ + get_platform_key from lib.util import atom_gyp, execute, get_atom_shell_version, parse_version, \ scoped_cwd from lib.github import GitHub @@ -24,14 +25,14 @@ OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R') DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') DIST_NAME = '{0}-{1}-{2}-{3}.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, - PLATFORM, + get_platform_key(), get_target_arch()) SYMBOLS_NAME = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, - PLATFORM, + get_platform_key(), get_target_arch()) MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION, - PLATFORM, + get_platform_key(), get_target_arch()) @@ -85,7 +86,7 @@ def main(): # Upload chromedriver and mksnapshot for minor version update. if parse_version(args.version)[2] == '0': chromedriver = 'chromedriver-{0}-{1}-{2}.zip'.format( - get_chromedriver_version(), PLATFORM, get_target_arch()) + get_chromedriver_version(), get_platform_key(), get_target_arch()) upload_atom_shell(github, release, os.path.join(DIST_DIR, chromedriver)) upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 60b630bc2ffc..ef60e6ab9ffb 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -18,6 +18,9 @@ describe 'crash-reporter module', -> # It is not working on 64bit Windows. return if process.platform is 'win32' and process.arch is 'x64' + # It is not working for mas build. + return if process.mas + # The crash-reporter test is not reliable on CI machine. isCI = remote.process.argv[2] == '--ci' return if isCI diff --git a/spec/package.json b/spec/package.json index 8f43b711f196..cf1d0abe89e3 100644 --- a/spec/package.json +++ b/spec/package.json @@ -5,14 +5,16 @@ "version": "0.1.0", "devDependencies": { "basic-auth": "^1.0.0", - "ffi": "2.0.0", "formidable": "1.0.16", "graceful-fs": "3.0.5", "mocha": "2.1.0", "q": "0.9.7", - "runas": "3.x", "temp": "0.8.1", "walkdir": "0.0.7", "ws": "0.7.2" + }, + "optionalDependencies": { + "ffi": "2.0.0", + "runas": "3.x" } } diff --git a/toolchain.gypi b/toolchain.gypi index 6977847106f7..23592d0473a7 100644 --- a/toolchain.gypi +++ b/toolchain.gypi @@ -9,6 +9,9 @@ 'sysroot%': '', 'variables': { + # The minimum OS X SDK version to use. + 'mac_sdk_min%': '10.10', + # Set ARM architecture version. 'arm_version%': 7, @@ -17,6 +20,7 @@ }, # Copy conditionally-set variables out one scope. + 'mac_sdk_min%': '<(mac_sdk_min)', 'arm_version%': '<(arm_version)', 'arm_neon%': '<(arm_neon)', @@ -35,6 +39,11 @@ 'source_root': ' [10, 6]""" + return map(int, re.findall(r'(\d+)', version_str)) + + +def main(): + parser = OptionParser() + parser.add_option("--verify", + action="store_true", dest="verify", default=False, + help="return the sdk argument and warn if it doesn't exist") + parser.add_option("--sdk_path", + action="store", type="string", dest="sdk_path", default="", + help="user-specified SDK path; bypasses verification") + parser.add_option("--print_sdk_path", + action="store_true", dest="print_sdk_path", default=False, + help="Additionaly print the path the SDK (appears first).") + options, args = parser.parse_args() + if len(args) != 1: + parser.error('Please specify a minimum SDK version') + min_sdk_version = args[0] + + job = subprocess.Popen(['xcode-select', '-print-path'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + out, err = job.communicate() + if job.returncode != 0: + print >> sys.stderr, out + print >> sys.stderr, err + raise Exception(('Error %d running xcode-select, you might have to run ' + '|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| ' + 'if you are using Xcode 4.') % job.returncode) + # The Developer folder moved in Xcode 4.3. + xcode43_sdk_path = os.path.join( + out.rstrip(), 'Platforms/MacOSX.platform/Developer/SDKs') + if os.path.isdir(xcode43_sdk_path): + sdk_dir = xcode43_sdk_path + else: + sdk_dir = os.path.join(out.rstrip(), 'SDKs') + sdks = [re.findall('^MacOSX(10\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)] + sdks = [s[0] for s in sdks if s] # [['10.5'], ['10.6']] => ['10.5', '10.6'] + sdks = [s for s in sdks # ['10.5', '10.6'] => ['10.6'] + if parse_version(s) >= parse_version(min_sdk_version)] + if not sdks: + raise Exception('No %s+ SDK found' % min_sdk_version) + best_sdk = sorted(sdks, key=parse_version)[0] + + if options.verify and best_sdk != min_sdk_version and not options.sdk_path: + print >> sys.stderr, '' + print >> sys.stderr, ' vvvvvvv' + print >> sys.stderr, '' + print >> sys.stderr, \ + 'This build requires the %s SDK, but it was not found on your system.' \ + % min_sdk_version + print >> sys.stderr, \ + 'Either install it, or explicitly set mac_sdk in your GYP_DEFINES.' + print >> sys.stderr, '' + print >> sys.stderr, ' ^^^^^^^' + print >> sys.stderr, '' + return min_sdk_version + + if options.print_sdk_path: + print subprocess.check_output(['xcodebuild', '-version', '-sdk', + 'macosx' + best_sdk, 'Path']).strip() + + return best_sdk + + +if __name__ == '__main__': + if sys.platform != 'darwin': + raise Exception("This script only runs on Mac") + print main() + sys.exit(0) diff --git a/vendor/brightray b/vendor/brightray index c25b9b27845a..fe2dd437c9ef 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit c25b9b27845a308e6a6a5966dad057d721b1f3d1 +Subproject commit fe2dd437c9ef7877bf9d454db8ae401965cd7cb0 diff --git a/vendor/crashpad b/vendor/crashpad index e6a0d433b0ee..5b777419c303 160000 --- a/vendor/crashpad +++ b/vendor/crashpad @@ -1 +1 @@ -Subproject commit e6a0d433b0ee399eecce2bef671794771052ffdb +Subproject commit 5b777419c303d8aa7930239d8ef755475f1ede57