From eeb1143debf7f6eab6592e6ff9e8328d560efab9 Mon Sep 17 00:00:00 2001 From: Ivan Kulikov Date: Fri, 27 Nov 2015 22:32:45 +0300 Subject: [PATCH 01/42] init russian lang docs --- README.md | 1 + docs-translations/ru-RU/README.md | 82 +++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 docs-translations/ru-RU/README.md diff --git a/README.md b/README.md index beb96b4e5..db82fac88 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ contains documents describing how to build and contribute to Electron. - [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es) - [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN) - [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) +- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU) ## Quick Start diff --git a/docs-translations/ru-RU/README.md b/docs-translations/ru-RU/README.md new file mode 100644 index 000000000..07e50028d --- /dev/null +++ b/docs-translations/ru-RU/README.md @@ -0,0 +1,82 @@ +Пожалуйста, убедитесь, что вы используете документацию, которые соответствует вашей версии Electron. +Номер версии должен быть частью адреса страницы. Если это не так, вы +возможно,используете документицию ветки разработки, которая может содержать изменения api, +которые не совместимы с вашей версией Electron. Если это так, +Вы можете переключиться на другую версию документации в списке +[доступные версии](http://electron.atom.io/docs/) на atom.io, или +если вы используете интерфейс GitHub, откройте список "переключение ветки/тега" и +выберите тег, который соответствует вашей версии. + +## Руководства + +* [Поддерживаемые платформы](tutorial/supported-platforms.md) +* [Application Distribution](tutorial/application-distribution.md) +* [Mac App Store Submission Guide](tutorial/mac-app-store-submission-guide.md) +* [Application Packaging](tutorial/application-packaging.md) +* [Using Native Node Modules](tutorial/using-native-node-modules.md) +* [Отладка главного процесса](tutorial/debugging-main-process.md) +* [Использование Selenium и WebDriver](tutorial/using-selenium-and-webdriver.md) +* [DevTools Extension](tutorial/devtools-extension.md) +* [Использование Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md) + +## Учебники + +* [Быстрый старт](tutorial/quick-start.md) +* [Desktop Environment Integration](tutorial/desktop-environment-integration.md) +* [Online/Offline Event Detection](tutorial/online-offline-events.md) + +## API References + +* [Краткий обзор](api/synopsis.md) +* [Process Object](api/process.md) +* [Поддерживаемые параметры командной строки Chrome](api/chrome-command-line-switches.md) + +### Пользовательские элементы DOM: + +* [`File` Object](api/file-object.md) +* [`` Tag](api/web-view-tag.md) +* [`window.open` Function](api/window-open.md) + +### Modules for the Main Process: + +* [app](api/app.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow](api/browser-window.md) +* [contentTracing](api/content-tracing.md) +* [dialog](api/dialog.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) +* [protocol](api/protocol.md) +* [session](api/session.md) +* [webContents](api/web-contents.md) +* [Tray](api/tray.md) + +### Модули для Renderer Process (Web Page): + +* [ipcRenderer](api/ipc-renderer.md) +* [remote](api/remote.md) +* [webFrame](api/web-frame.md) + +### Modules for Both Processes: + +* [clipboard](api/clipboard.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Разработка + +* [Стиль кодирования](development/coding-style.md) +* [Source Code Directory Structure](development/source-code-directory-structure.md) +* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Обзор системы сборки](development/build-system-overview.md) +* [Инструкции по сборке (OS X)](development/build-instructions-osx.md) +* [Инструкции по сборке (Windows)](development/build-instructions-windows.md) +* [Инструкции по сборке (Linux)](development/build-instructions-linux.md) +* [Настройка сервера символов для отладчика](development/setting-up-symbol-server.md) + From 5bbc46930fef4d9445ce148cebac4e94560572c3 Mon Sep 17 00:00:00 2001 From: "howard.zuo" Date: Sun, 29 Nov 2015 12:14:49 +0800 Subject: [PATCH 02/42] add packaging translation for ZH-CN --- .../zh-CN/tutorial/application-packaging.md | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 docs-translations/zh-CN/tutorial/application-packaging.md diff --git a/docs-translations/zh-CN/tutorial/application-packaging.md b/docs-translations/zh-CN/tutorial/application-packaging.md new file mode 100644 index 000000000..ee4b7bf63 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/application-packaging.md @@ -0,0 +1,141 @@ +# 应用打包 + +为舒缓Windows下路径名过长的问题[issues](https://github.com/joyent/node/issues/6960), 也略对`require`加速以及简单隐匿你的源代码, 你可以通过极小的源代码改动将你的应用打包成[asar][asar]. + +## 生成`asar`包 + +[asar][asar]是一种将多个文件合并成一个文件的类tar风格的归档格式。 Electron可以无需解压,即从其中读取任意文件内容。 + +参照如下步骤将你的应用打包成`asar`: + +### 1. 安装asar + +```bash +$ npm install -g asar +``` + +### 2. 用`asar pack`打包 + +```bash +$ asar pack your-app app.asar +``` + +## 使用`asar`包 + +在Electron中有两类APIs:Node.js提供的Node APIs和Chromium提供的Web APIs。这两种APIs都支持从`asar`包中读取文件。 + +### Node API + +由于Electron中打了特别补丁, Node APIs中如`fs.readFile`或者`require`之类的方法可以将`asar`视之为虚拟文件夹,读取`asar`里面的文件就和从真实的文件系统中读取一样。 + +例如,假设我们在`/path/to`文件夹下有个`example.asar`包: + +```bash +$ asar list /path/to/example.asar +/app.js +/file.txt +/dir/module.js +/static/index.html +/static/main.css +/static/jquery.min.js +``` + +从`asar`包读取一个文件: + +```javascript +const fs = require('fs'); +fs.readFileSync('/path/to/example.asar/file.txt'); +``` + +列出`asar`包中根目录下的所有文件: + +```javascript +const fs = require('fs'); +fs.readdirSync('/path/to/example.asar'); +``` + +使用`asar`包中的一个模块: + +```javascript +require('/path/to/example.asar/dir/module.js'); +``` + +你也可以使用`BrowserWindow`来显示一个`asar`包里的web页面: + +```javascript +const BrowserWindow = require('electron').BrowserWindow; +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL('file:///path/to/example.asar/static/index.html'); +``` + +### Web API + +在Web页面里,用`file:`协议可以获取`asar`包中文件。和Node API一样,视`asar`包如虚拟文件夹。 + +例如,用`$.get`获取文件: + +```html + +``` + +### 像“文件”那样处理`asar`包 + +有些场景,如:核查`asar`包的校验和,我们需要像读取“文件”那样读取`asar`包的内容(而不是当成虚拟文件夹)。你可以使用内置的`original-fs`(提供和`fs`一样的APIs)模块来读取`asar`包的真实信息。 + +```javascript +var originalFs = require('original-fs'); +originalFs.readFileSync('/path/to/example.asar'); +``` + +## Node API缺陷 + +尽管我们已经尽了最大努力使得`asar`包在Node API下的应用尽可能的趋向于真实的目录结构,但仍有一些底层Node API我们无法保证其正常工作。 + +### `asar`包是只读的 + +`asar`包中的内容不可更改,所以Node APIs里那些可以用来修改文件的方法在对待`asar`包时都无法正常工作。 + +### Working Directory在`asar`包中无效 + +尽管`asar`包是虚拟文件夹,但其实并没有真实的目录架构对应在文件系统里,所以你不可能将working Directory设置成`asar`包里的一个文件夹。将`asar`中的文件夹以`cwd`形式作为参数传入一些API中也会报错。 + +### API中的额外“开箱” + +大部分`fs`API可以无需解压即从`asar`包中读取文件或者文件的信息,但是在处理一些依赖真实文件路径的底层系统方法时,Electron会将所需文件解压到临时目录下,然后将临时目录下的真实文件路径传给底层系统方法使其正常工作。 对于这类API,耗费会略多一些。 + +以下是一些需要额外解压的APIs: + +* `child_process.execFile` +* `child_process.execFileSync` +* `fs.open` +* `fs.openSync` +* `process.dlopen` - `require`native模块时用到 + +### `fs.stat`获取的stat信息不可靠 + +对`asar`包中的文件取`fs.stat`,返回的`Stats`对象不是精确值,因为这些文件不是真实存在于文件系统里。所以除了文件大小和文件类型以外,你不应该依赖`Stats`对象的值。 + +### 执行`asar`包中的程序 + +Node中有一些可以执行程序的API,如`child_process.exec`,`child_process.spawn`和`child_process.execFile`等,但只有`execFile`可以执行`asar`包中的程序。 + +因为`exec`和`spawn`允许`command`替代`file`作为输入,而`command`是需要在shell下执行的,目前没有可靠的方法来判断`command`中是否在操作一个`asar`包中的文件,而且即便可以判断,我们依旧无法保证可以在无任何副作用的情况下替换`command`中的文件路径。 + +## 打包时排除文件 + +如上所述,一些Node API会在调用时将文件解压到文件系统中,除了效率问题外,也有可能引起杀毒软件的注意! + +为解决这个问题,你可以在生成`asar`包时使用`--unpack`选项来排除一些文件,使其不打包到`asar`包中,下面是如何排除一些用作共享用途的native模块的方法: + +```bash +$ asar pack app app.asar --unpack *.node +``` + +经过上述命令后,除了生成的`app.asar`包以外,还有一个包含了排除文件的`app.asar.unpacked`文件夹,你需要将这个文件夹一起拷贝,提供给用户。 + +[asar]: https://github.com/atom/asar From df9ecefe015913fe0053e79cb7a3c448dc8deb7b Mon Sep 17 00:00:00 2001 From: Luke Westby Date: Sun, 29 Nov 2015 12:22:53 -0600 Subject: [PATCH 03/42] fix typo in "rotation" string --- atom/browser/api/atom_api_screen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_screen.cc b/atom/browser/api/atom_api_screen.cc index b73bda9ce..407a71f0c 100644 --- a/atom/browser/api/atom_api_screen.cc +++ b/atom/browser/api/atom_api_screen.cc @@ -41,7 +41,7 @@ std::vector MetricsToArray(uint32_t metrics) { if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR) array.push_back("scaleFactor"); if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION) - array.push_back("rotaion"); + array.push_back("rotation"); return array; } From c7420e17ab0e74dfcfbcf5a53f0c13f35104d107 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 29 Nov 2015 14:04:57 -0500 Subject: [PATCH 04/42] Suggest [ci skip] in documentation-only commits --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ca3ea5d2..31e31edf1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,6 +57,7 @@ possible with your report. If you can, please include: * Use the imperative mood ("Move cursor to..." not "Moves cursor to...") * Limit the first line to 72 characters or less * Reference issues and pull requests liberally +* When only changing documentation, include [ci skip] in the commit description * Consider starting the commit message with an applicable emoji: * :art: `:art:` when improving the format/structure of the code * :racehorse: `:racehorse:` when improving performance From 9c0afcd9017966125eb8605f683e202d70a062de Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 29 Nov 2015 14:57:48 -0500 Subject: [PATCH 05/42] Wrap [ci skip] in backticks --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31e31edf1..630b8b0ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,7 +57,7 @@ possible with your report. If you can, please include: * Use the imperative mood ("Move cursor to..." not "Moves cursor to...") * Limit the first line to 72 characters or less * Reference issues and pull requests liberally -* When only changing documentation, include [ci skip] in the commit description +* When only changing documentation, include `[ci skip]` in the commit description * Consider starting the commit message with an applicable emoji: * :art: `:art:` when improving the format/structure of the code * :racehorse: `:racehorse:` when improving performance From 7d827c2f3e1734db241d37f04101c9cdde449b8e Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Sun, 29 Nov 2015 22:56:34 -0200 Subject: [PATCH 06/42] Remove 'Google Translator'-like translation --- .../pt-BR/development/coding-style.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/docs-translations/pt-BR/development/coding-style.md b/docs-translations/pt-BR/development/coding-style.md index f3b4d6d58..b0068d568 100644 --- a/docs-translations/pt-BR/development/coding-style.md +++ b/docs-translations/pt-BR/development/coding-style.md @@ -2,28 +2,25 @@ Estas são as diretrizes de estilo para codificar no Electron. -## C++ and Python +## C++ e Python -Para C ++ e Python, seguimos os padrões do projeto Chromium [Estilo de Codificação](http://www.chromium.org/developers/coding-style). Há também um +Para C++ e Python, seguimos o [Estilo de Codificação](http://www.chromium.org/developers/coding-style) do projeto Chromium. Há também um script `script/cpplint.py` para verificar se todos os arquivos estão em conformidade. A versão Python que estamos usando agora é a Python 2.7. -O código C ++ usa do Chromium's um monte de tipos e abstrações, por isso é recomendada para se familiarizar com eles. Um bom lugar para começar com a documentação do Chromium's [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures). O documento menciona alguns tipos especiais, com escopo tipos (que automaticamente libera sua memória quando sai do escopo), registrando mecanismos etc. +O código C++ usa várias abstrações e tipos do Chromium, por isso é recomendado familiarizar-se com eles. Um bom lugar para começar é com a documentação do Chromium [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures). O documento menciona alguns tipos especiais, *scoped types* (que automaticamente liberam sua memória ao sair do escopo), mecanismos de *log* etc. ## CoffeeScript -For CoffeeScript, we follow GitHub's [Style -Guide](https://github.com/styleguide/javascript) and the following rules: +Para CoffeeScript, seguimos o [Guia de Estilo] (https://github.com/styleguide/javascript) do GitHub com as seguintes regras: -Para CoffeeScript, seguimos o estilo do GitHub [Guia de Estilo] (https://github.com/styleguide/javascript) com as seguintes regras: +* Os arquivos **NÃO DEVEM** terminar com uma nova linha, porque queremos corresponder aos padrões de estilo Google. -* Os arquivos devem **NÃO DEVEM** com nova linha no final, porque queremos corresponder aos padrões de estilo Google. - -* Os nomes dos arquivos devem ser concatenados com o `-` em vez de`_`, por exemplo, `file-name.coffee` em vez de`file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente em o formulário `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`. +* Os nomes dos arquivos devem ser concatenados com `-` em vez de `_`, por exemplo, `file-name.coffee` em vez de `file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente da forma `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`. * -## API Names +## Nomes de APIs -Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez de -estilo de uma função do jQuery. Por exemplo, `.getText()` e `.setText(text)` utilize `.text([text])`. Existe uma +Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez do +estilo de uma função única do jQuery. Por exemplo, `.getText()` e `.setText(text)` são preferenciais a `.text([text])`. Existe uma [discussão](https://github.com/atom/electron/issues/46) sobre este assunto. From 45e9ed5f0c61fe8fbd4a3c2ff4c559c0ce0b08f2 Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Sun, 29 Nov 2015 23:25:16 -0200 Subject: [PATCH 07/42] =?UTF-8?q?Update=20'Estilo=20de=20c=C3=B3digo'=20li?= =?UTF-8?q?nk.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'Estilo de código' in 'Desenvolvimento' section now points to the translated coding-style.md --- docs-translations/pt-BR/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md index db88edaf7..1641f2380 100644 --- a/docs-translations/pt-BR/README.md +++ b/docs-translations/pt-BR/README.md @@ -61,7 +61,7 @@ Módulos de ambos os processos: ## Desenvolvimento -* [Estilo de código](../../docs/development/coding-style.md) +* [Estilo de código](development/coding-style.md) * [Estrutura de diretórios padrão](../../docs/development/source-code-directory-structure.md) * [Diferenças técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) * [Visão geral do build](../../docs/development/build-system-overview.md) From bf4b94561ef38c29ebace0c557686795c03d29d3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 30 Nov 2015 15:21:39 +0800 Subject: [PATCH 08/42] docs: Mention submitting to MAC costs money Close #3617. --- docs/tutorial/mac-app-store-submission-guide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 43b2d9a0a..036676fe8 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -4,6 +4,9 @@ Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store (MAS). This guide provides information on: how to submit your app and the limitations of the MAS build. +__Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer +Program][developer-program], which costs money. + ## How to Submit Your App The following steps introduce a simple way to submit your app to Mac App Store. @@ -108,6 +111,7 @@ Also, due to the usage of app sandboxing, the resources which can be accessed by the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for more information. +[developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html [nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps [enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html From 4d5028fb4c8e4643a16ea866ea318821f7c10994 Mon Sep 17 00:00:00 2001 From: Smite Chow Date: Mon, 30 Nov 2015 17:16:35 +0800 Subject: [PATCH 09/42] :art: add miss charactor --- .../zh-CN/development/atom-shell-vs-node-webkit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md b/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md index 9774580ee..beea91e3f 100644 --- a/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md @@ -12,7 +12,7 @@ __1. 应用的入口__ 在 Electron 中,入口是一个 JavaScript 脚本。不同于直接提供一个URL,你需要手动创建一个浏览器窗口,然后通过 API 加载 HTML 文件。你还可以监听窗口事件,决定何时让应用退出。 -Electron 的工作方式更像 Node.js 运行时。 Electron 的 APIs 更加底层,因此你可以它替代 [PhantomJS](http://phantomjs.org/) 做浏览器测试。 +Electron 的工作方式更像 Node.js 运行时。 Electron 的 APIs 更加底层,因此你可以用它替代 [PhantomJS](http://phantomjs.org/) 做浏览器测试。 __2. 构建系统__ From 44e24ebf7adc5a6242085b35ed4150950b4eb560 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 30 Nov 2015 22:29:01 +0800 Subject: [PATCH 10/42] Delete BridgeTaskRunner when main message loop is ready --- atom/browser/atom_browser_main_parts.cc | 3 ++- atom/browser/bridge_task_runner.cc | 5 ----- atom/browser/bridge_task_runner.h | 6 +++--- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 0a8c16ca2..3bfe3748f 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -114,7 +114,8 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { 1000)); brightray::BrowserMainParts::PreMainMessageLoopRun(); - BridgeTaskRunner::MessageLoopIsReady(); + bridge_task_runner_->MessageLoopIsReady(); + bridge_task_runner_ = nullptr; #if defined(USE_X11) libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); diff --git a/atom/browser/bridge_task_runner.cc b/atom/browser/bridge_task_runner.cc index 882a3050d..36c8d1735 100644 --- a/atom/browser/bridge_task_runner.cc +++ b/atom/browser/bridge_task_runner.cc @@ -8,11 +8,6 @@ namespace atom { -// static -std::vector BridgeTaskRunner::tasks_; -std::vector BridgeTaskRunner::non_nestable_tasks_; - -// static void BridgeTaskRunner::MessageLoopIsReady() { auto message_loop = base::MessageLoop::current(); CHECK(message_loop); diff --git a/atom/browser/bridge_task_runner.h b/atom/browser/bridge_task_runner.h index 12508f009..b69b33b29 100644 --- a/atom/browser/bridge_task_runner.h +++ b/atom/browser/bridge_task_runner.h @@ -20,7 +20,7 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner { ~BridgeTaskRunner() override {} // Called when message loop is ready. - static void MessageLoopIsReady(); + void MessageLoopIsReady(); // base::SingleThreadTaskRunner: bool PostDelayedTask(const tracked_objects::Location& from_here, @@ -35,8 +35,8 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner { private: using TaskPair = base::Tuple< tracked_objects::Location, base::Closure, base::TimeDelta>; - static std::vector tasks_; - static std::vector non_nestable_tasks_; + std::vector tasks_; + std::vector non_nestable_tasks_; DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner); }; From 7622bb40a95801d5cca594925e83b2c540cb957a Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 23 Nov 2015 23:29:49 -0800 Subject: [PATCH 11/42] Enable all origins via CORS header for custom schemes This PR disables CORS for custom schemes, which allows you to serve Font resources from custom schemes after using registerCustomSchemeAsSecure --- atom/browser/net/url_request_buffer_job.cc | 3 +++ atom/browser/net/url_request_buffer_job.h | 2 ++ atom/browser/net/url_request_string_job.cc | 3 +++ 3 files changed, 8 insertions(+) diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index affc3dd37..c4936ba15 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -50,6 +50,9 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) { status.append("\0\0", 2); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + std::string cors("Access-Control-Allow-Origin: *"); + headers->AddHeader(cors); + if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); content_type_header.append(": "); diff --git a/atom/browser/net/url_request_buffer_job.h b/atom/browser/net/url_request_buffer_job.h index ab8de7e8f..8de5d82e0 100644 --- a/atom/browser/net/url_request_buffer_job.h +++ b/atom/browser/net/url_request_buffer_job.h @@ -12,6 +12,8 @@ #include "net/http/http_status_code.h" #include "net/url_request/url_request_simple_job.h" +const std::string kCorsHeader("Access-Control-Allow-Origin: *"); + namespace atom { class URLRequestBufferJob : public JsAsker { diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index 4a631b813..5d7a7dd01 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -32,6 +32,9 @@ void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + std::string cors("Access-Control-Allow-Origin: *"); + headers->AddHeader(cors); + if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); content_type_header.append(": "); From 65cb1488b0e32034d17ba3f8753b7dca015828aa Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 25 Nov 2015 15:00:34 -0800 Subject: [PATCH 12/42] Fix CORS header code to be cleaner --- atom/browser/net/js_asker.cc | 2 ++ atom/browser/net/js_asker.h | 1 + atom/browser/net/url_request_buffer_job.cc | 3 +-- atom/browser/net/url_request_string_job.cc | 3 +-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index 8f0d1d2b9..0e232feff 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -11,6 +11,8 @@ namespace atom { +const std::string kCorsHeader("Access-Control-Allow-Origin: *"); + namespace internal { namespace { diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index 8ec245ee8..cdc0417f3 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -17,6 +17,7 @@ #include "v8/include/v8.h" namespace atom { +extern const std::string kCorsHeader; using JavaScriptHandler = base::Callback)>; diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index c4936ba15..55603e77e 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -50,8 +50,7 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) { status.append("\0\0", 2); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); - std::string cors("Access-Control-Allow-Origin: *"); - headers->AddHeader(cors); + headers->AddHeader(kCorsHeader); if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index 5d7a7dd01..6a12026b2 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -32,8 +32,7 @@ void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); - std::string cors("Access-Control-Allow-Origin: *"); - headers->AddHeader(cors); + headers->AddHeader(kCorsHeader); if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); From 7cce3987eb0a91ae481c53568c378ea3a115a720 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 25 Nov 2015 15:00:47 -0800 Subject: [PATCH 13/42] Add CORS header to file jobs --- atom/browser/net/url_request_async_asar_job.cc | 9 +++++++++ atom/browser/net/url_request_async_asar_job.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index 303bfc017..86d92071e 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -34,4 +34,13 @@ void URLRequestAsyncAsarJob::StartAsync(scoped_ptr options) { } } + +void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { + std::string status("HTTP/1.1 200 OK"); + net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + + headers->AddHeader(kCorsHeader); + info->headers = headers; +} + } // namespace atom diff --git a/atom/browser/net/url_request_async_asar_job.h b/atom/browser/net/url_request_async_asar_job.h index df1aed350..d65142f0b 100644 --- a/atom/browser/net/url_request_async_asar_job.h +++ b/atom/browser/net/url_request_async_asar_job.h @@ -18,6 +18,9 @@ class URLRequestAsyncAsarJob : public JsAsker { // JsAsker: void StartAsync(scoped_ptr options) override; + // URLRequestJob: + void GetResponseInfo(net::HttpResponseInfo* info) override; + private: DISALLOW_COPY_AND_ASSIGN(URLRequestAsyncAsarJob); }; From 15b8d7680ecbfb86168acdbdfe218d9ab962273d Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 25 Nov 2015 15:20:50 -0800 Subject: [PATCH 14/42] Add tests to verify behavior --- spec/api-protocol-spec.coffee | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index d160512cd..5332b2b17 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -81,6 +81,21 @@ describe 'protocol module', -> error: (xhr, errorType, error) -> done(error) + it 'sets Access-Control-Allow-Origin', (done) -> + handler = (request, callback) -> callback(text) + protocol.registerStringProtocol protocolName, handler, (error) -> + return done(error) if error + $.ajax + url: "#{protocolName}://fake-host" + success: (data, status, request) -> + assert.equal data, text + assert.equal( + request.getResponseHeader('Access-Control-Allow-Origin'), + '*') + done() + error: (xhr, errorType, error) -> + done(error) + it 'sends object as response', (done) -> handler = (request, callback) -> callback(data: text, mimeType: 'text/html') protocol.registerStringProtocol protocolName, handler, (error) -> @@ -120,6 +135,21 @@ describe 'protocol module', -> error: (xhr, errorType, error) -> done(error) + it 'sets Access-Control-Allow-Origin', (done) -> + handler = (request, callback) -> callback(buffer) + protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error + $.ajax + url: "#{protocolName}://fake-host" + success: (data, status, request) -> + assert.equal data, text + assert.equal( + request.getResponseHeader('Access-Control-Allow-Origin'), + '*') + done() + error: (xhr, errorType, error) -> + done(error) + it 'sends object as response', (done) -> handler = (request, callback) -> callback(data: buffer, mimeType: 'text/html') protocol.registerBufferProtocol protocolName, handler, (error) -> @@ -163,6 +193,21 @@ describe 'protocol module', -> error: (xhr, errorType, error) -> done(error) + it 'sets Access-Control-Allow-Origin', (done) -> + handler = (request, callback) -> callback(filePath) + protocol.registerFileProtocol protocolName, handler, (error) -> + return done(error) if error + $.ajax + url: "#{protocolName}://fake-host" + success: (data, status, request) -> + assert.equal data, String(fileContent) + assert.equal( + request.getResponseHeader('Access-Control-Allow-Origin'), + '*') + done() + error: (xhr, errorType, error) -> + done(error) + it 'sends object as response', (done) -> handler = (request, callback) -> callback(path: filePath) protocol.registerFileProtocol protocolName, handler, (error) -> From 549da7fd91325b2370716fadfa2bc1a177593fe6 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 30 Nov 2015 11:08:22 -0800 Subject: [PATCH 15/42] Linting --- atom/browser/net/js_asker.h | 2 ++ atom/browser/net/url_request_buffer_job.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index cdc0417f3..b353b98fa 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -5,6 +5,8 @@ #ifndef ATOM_BROWSER_NET_JS_ASKER_H_ #define ATOM_BROWSER_NET_JS_ASKER_H_ +#include + #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" diff --git a/atom/browser/net/url_request_buffer_job.h b/atom/browser/net/url_request_buffer_job.h index 8de5d82e0..ab8de7e8f 100644 --- a/atom/browser/net/url_request_buffer_job.h +++ b/atom/browser/net/url_request_buffer_job.h @@ -12,8 +12,6 @@ #include "net/http/http_status_code.h" #include "net/url_request/url_request_simple_job.h" -const std::string kCorsHeader("Access-Control-Allow-Origin: *"); - namespace atom { class URLRequestBufferJob : public JsAsker { From c83976dfdc1444d1aa2a1d90bab873186d6c533a Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Mon, 30 Nov 2015 19:14:33 -0200 Subject: [PATCH 16/42] :memo: [ci skip] Fix typos --- .../pt-BR/tutorial/quick-start.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs-translations/pt-BR/tutorial/quick-start.md b/docs-translations/pt-BR/tutorial/quick-start.md index f9883144c..eecf67878 100644 --- a/docs-translations/pt-BR/tutorial/quick-start.md +++ b/docs-translations/pt-BR/tutorial/quick-start.md @@ -4,7 +4,7 @@ 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 +Isso não significa que o Electron é uma ligação em JavaScript para bibliotecas 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. @@ -17,13 +17,13 @@ mostrar uma GUI criando páginas web. ### Processo Renderizador -Desde que o Electron usa o Chromium para mostrar as páginas web, a arquitetura +Já 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 +e não têm permissão de acesso para recursos nativos. Usuários Electron, entretanto, +têm 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 @@ -33,12 +33,12 @@ Cada instância de `BrowserWindow` roda a página web em seu próprio processo r 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 +O processo principal gerencia 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 +gerenciar 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. @@ -52,26 +52,26 @@ módulo [remoto](../../../docs/api/remote.md) para comunicação RPC. Geralmente, um app Electron é estruturado assim: ```text -your-app/ +seu-app/ ├── package.json ├── main.js └── index.html ``` -O formato de `package.json` é exatamente o mesmo que os dos módulos do Node, e +O formato de `package.json` é exatamente o mesmo que o dos módulos do Node, 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", + "name" : "seu-app", "version" : "0.1.0", "main" : "main.js" } ``` -__Nota__: Se o campo `main` não estiver presente no `package.jso`, o Electron irá +__Nota__: Se o campo `main` não estiver presente no `package.json`, 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 @@ -140,8 +140,8 @@ Finalmente o `index.html` é a página web que você quer mostrar: ## 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 +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 e ter certeza que funciona como você espera. ### electron-prebuilt @@ -167,19 +167,19 @@ executar seu app diretamente. #### Windows ```bash -$ .\electron\electron.exe your-app\ +$ .\electron\electron.exe seu-app\ ``` #### Linux ```bash -$ ./electron/electron your-app/ +$ ./electron/electron seu-app/ ``` #### OS X ```bash -$ ./Electron.app/Contents/MacOS/Electron your-app/ +$ ./Electron.app/Contents/MacOS/Electron seu-app/ ``` `Electron.app` aqui é uma parte do pacote de lançamento do Electron, você pode baixa-lo @@ -188,5 +188,5 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ ### 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 +[Distribuição de aplicações](./application-distribution.md) e então executar o app empacotado. From 97f535251b215a515db7af2a1c79453926a025d9 Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Mon, 30 Nov 2015 19:43:19 -0200 Subject: [PATCH 17/42] :memo: [ci skip] Update to match english docs. --- docs-translations/pt-BR/README.md | 77 ++++++++++++++++++------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md index 1641f2380..61202f8ca 100644 --- a/docs-translations/pt-BR/README.md +++ b/docs-translations/pt-BR/README.md @@ -1,71 +1,82 @@ +Por favor, certifique-se de que está utilizando a documentação que corresponde à sua versão do Electron. +O número da versão deve ser uma parte da URL da página. Se não for, você provavelmente está utilizando +a documentação de um branch de desenvolvimento que pode conter mudanças na API que não são compatíveis +com a sua versão do Electron. Se este for o caso, você pode mudar para uma versão diferente da +documentação na lista de [versões disponíveis](http://electron.atom.io/docs/) em atom.io, +ou se você estiver usando a interface do GitHub, abra o *dropdown* "Switch branches/tags" e +selecione a *tag* que corresponde à sua versão. + ## Guias +* [Platformas Suportadas](../../tutorial/supported-platforms.md) * [Distribuição de Aplicações](tutorial/application-distribution.md) -* [Empacotamento da aplicação](tutorial/application-packaging.md) -* [Usando módulos nativos](tutorial/using-native-node-modules.md) -* [Depuração do processo principal](tutorial/debugging-main-process.md) +* [Guia de Submissão da Mac App Store](../../tutorial/mac-app-store-submission-guide.md) +* [Empacotamento da Aplicação](tutorial/application-packaging.md) +* [Usando Módulos Nativos do Node](tutorial/using-native-node-modules.md) +* [Depuração do Processo Principal](tutorial/debugging-main-process.md) * [Usando Selenium e WebDriver](../../docs/tutorial/using-selenium-and-webdriver.md) * [Extensão DevTools](../../docs/tutorial/devtools-extension.md) -* [Usando o plugin papper flash](tutorial/using-pepper-flash-plugin.md) +* [Usando o Plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md) ## Tutoriais * [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) +* [Integração com o Ambiente de Desenvolvimento](tutorial/desktop-environment-integration.md) +* [Evento de Detecção Online/Offline](tutorial/online-offline-events.md) -## API - Referencias +## API - Referências * [Sinopse](../../docs/api/synopsis.md) * [Processos](api/process.md) * [Aceleradores (Teclas de Atalho)](api/accelerator.md) * [Parâmetros CLI suportados (Chrome)](../../docs/api/chrome-command-line-switches.md) +* [Variáveis de Ambiente](../../docs/api/environment-variables.md) -DOM elementos personalizados: +### Elementos DOM Personalizados: * [Objeto `File`](../../docs/api/file-object.md) * [Tag ``](../../docs/api/web-view-tag.md) * [Função `window.open`](../../docs/api/window-open.md) -Os principais módulos: +### Módulos para o Processo Principal: * [app](../../docs/api/app.md) -* [auto-updater](../../docs/api/auto-updater.md) -* [browser-window](../../docs/api/browser-window.md) -* [content-tracing](../../docs/api/content-tracing.md) +* [autoUpdater](../../docs/api/auto-updater.md) +* [BrowserWindow](../../docs/api/browser-window.md) +* [contentTracing](../../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) -* [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) +* [globalShortcut](../../docs/api/global-shortcut.md) +* [ipcMain](../../docs/api/ipc-main-process.md) +* [Menu](../../docs/api/menu.md) +* [MenuItem](../../docs/api/menu-item.md) +* [powerMonitor](../../docs/api/power-monitor.md) +* [powerSaveBlocker](../../docs/api/power-save-blocker.md) * [protocol](../../docs/api/protocol.md) * [session](../../docs/api/session.md) * [webContents](../../docs/api/web-contents.md) -* [tray](../../docs/api/tray.md) +* [Tray](../../docs/api/tray.md) -Módulos do renderizador (web page): +### Módulos para o Processo Renderizador: -* [ipc (renderer)](../../docs/api/ipc-renderer.md) +* [ipcRenderer](../../docs/api/ipc-renderer.md) * [remote](../../docs/api/remote.md) -* [web-frame](../../docs/api/web-frame.md) +* [webFrame](../../docs/api/web-frame.md) -Módulos de ambos os processos: +### Módulos para ambos os processos: * [clipboard](../../docs/api/clipboard.md) -* [crash-reporter](../../docs/api/crash-reporter.md) -* [native-image](../../docs/api/native-image.md) +* [crashReporter](../../docs/api/crash-reporter.md) +* [nativeImage](../../docs/api/native-image.md) * [screen](../../docs/api/screen.md) * [shell](api/shell.md) ## Desenvolvimento -* [Estilo de código](development/coding-style.md) -* [Estrutura de diretórios padrão](../../docs/development/source-code-directory-structure.md) -* [Diferenças técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) -* [Visão geral do build](../../docs/development/build-system-overview.md) -* [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) +* [Estilo de Código](development/coding-style.md) +* [Estrutura de Diretórios de Código Fonte](../../docs/development/source-code-directory-structure.md) +* [Diferenças Técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) +* [Visão Geral do Build](../../docs/development/build-system-overview.md) +* [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) From 7da78a9fa8ffdd0d9300bb12892683de6a154a5d Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Mon, 30 Nov 2015 21:56:19 -0200 Subject: [PATCH 18/42] :memo: [ci skip] Add translation to app.md --- docs-translations/pt-BR/api/app.md | 452 +++++++++++++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 docs-translations/pt-BR/api/app.md diff --git a/docs-translations/pt-BR/api/app.md b/docs-translations/pt-BR/api/app.md new file mode 100644 index 000000000..85cfaade5 --- /dev/null +++ b/docs-translations/pt-BR/api/app.md @@ -0,0 +1,452 @@ +# app + +O módulo `app` é responsável por controlar o ciclo de vida do aplicativo. + +O exemplo a seguir mostra como fechar o aplicativo quando a última janela é fechada: + +```javascript +const app = require('electron').app; +app.on('window-all-closed', function() { + app.quit(); +}); +``` + +## Eventos + +O objeto `app` emite os seguintes eventos: + +### Evento: 'will-finish-launching' + +Emitido quando o aplicativo finaliza a inicialização básica. No Windows e no Linux, +o evento `will-finish-launching` é o mesmo que o evento `ready`; No OS X, +esse evento representa a notificação `applicationWillFinishLaunching` do `NSApplication`. +Normalmente aqui seriam criados *listeners* para os eventos `open-file` e `open-url`, e inicializar o *crash reporter* e atualizador automático. + +Na maioria dos casos, você deve fazer tudo no manipulador de eventos do `ready`. + +### Evento: 'ready' + +Emitido quando o Electron finaliza a inicialização. + +### Evento: 'window-all-closed' + +Emitido quando todas as janelas forem fechadas. + +Este evento só é emitido quando o aplicativo não for fechar. Se o +usuário pressionou`Cmd + Q`, ou o desenvolvedor chamou `app.quit()`, +o Electron tentará primeiro fechar todas as janelas e então emitir o +evento `will-quit`, e neste caso o evento `window-all-closed` não +seria emitido. + +### Evento: 'before-quit' + +Retorna: + +* `event` Event + +Emitido antes que o aplicativo comece a fechar suas janelas. +Chamar `event.preventDefault()` irá impedir o comportamento padrão, +que é terminar o aplicativo. + +### Evento: 'will-quit' + +Retorna: + +* `event` Event + +Emitido quando todas as janelas foram fechadas e o aplicativo irá finalizar. +Chamar `event.preventDefault()` irá impedir o comportamento padrão, +que é terminar o aplicativo. + +Veja a descrição do evento `window-all-closed` para as diferenças entre o +evento `will-quit` e `window-all-closed`. + +### Evento: 'quit' + +Emitido quando o aplicativo está finalizando. + +### Evento: 'open-file' _OS X_ + +Retorna: + +* `event` Event +* `path` String + +Emitido quando o usuário deseja abrir um arquivo com o aplicativo. O evento +`open-file` normalmente é emitido quando o aplicativo já está aberto e o S.O. +quer reutilizar o aplicativo para abrir o arquivo. `open-file` também é emitido +quando um arquivo é jogado no *dock* e o aplicativo ainda não está rodando. +Certifique-se de utilizar um *listener* para o evento `open-file` cedo na +inicialização do seu aplicativo para cuidar deste caso (antes mesmo do evento +`ready` ser emitido). + +Você deve chamar `event.preventDefault()` se quiser cuidar deste caso. + +No Windows, você deve fazer o *parse* do `process.argv` para pegar o +endereço do arquivo. + +### Evento: 'open-url' _OS X_ + +Retorna: + +* `event` Event +* `url` String + +Emitido quando o usuário deseja abrir uma URL com o aplicativo. O esquema deve +ser registrado para ser aberto pelo seu aplicativo. + +Você deve chamar `event.preventDefault()` se quiser cuidar deste caso. + +### Evento: 'activate' _OS X_ + +Retorna: + +* `event` Event +* `hasVisibleWindows` Boolean + +Emitido quando o aplicativo é ativado, que normalmente acontece quando o ícone +do aplicativo no *dock* é clicado. + +### Evento: 'browser-window-blur' + +Retorna: + +* `event` Event +* `window` BrowserWindow + +Emitido quando uma [browserWindow](../../../docs/api/browser-window.md) fica embaçada. + +### Evento: 'browser-window-focus' + +Retorna: + +* `event` Event +* `window` BrowserWindow + +Emitido quando uma [browserWindow](../../../docs/api/browser-window.md) é focada. + +### Evento: 'browser-window-created' + +Retorna: + +* `event` Event +* `window` BrowserWindow + +Emitido quando uma nova [browserWindow](../../../docs/api/browser-window.md) é criada. + +### Evento: 'certificate-error' + +Returns: + +* `event` Event +* `webContents` [WebContents](../../../docs/api/web-contents.md) +* `url` URL +* `error` String - O código de erro +* `certificate` Object + * `data` Buffer - dados codificados PEM + * `issuerName` String +* `callback` Function + +Emitido quando há uma falha na verificação do `certificate` para a `url`, +para confiar no certificado, você deve impedir o comportamento padrão com +`event.preventDefault()` e chamar `callback(true)`. + +```javascript +session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { + if (url == "https://github.com") { + // Lógica de verificação. + event.preventDefault(); + callback(true); + } else { + callback(false); + } +}); +``` + +### Evento: 'select-client-certificate' + +Retorna: + +* `event` Event +* `webContents` [WebContents](../../../docs/api/web-contents.md) +* `url` URL +* `certificateList` [Objects] + * `data` Buffer - dados codificados PEM + * `issuerName` String - Nome Comum do Emissor +* `callback` Function + +Emitido quando um certificado de cliente é requisitado. + +A `url` corresponde à entrada de navegação requisitando o certificado do +cliente e `callback` precisa ser chamada com uma entrada filtrada da lista. +Usar `event.preventDefault()` impede o aplicativo de usar o primeiro certificado +da memória. + +```javascript +app.on('select-client-certificate', function(event, webContents, url, list, callback) { + event.preventDefault(); + callback(list[0]); +}) +``` + +### Evento: 'login' + +Retorna: + +* `event` Event +* `webContents` [WebContents](../../../docs/api/web-contents.md) +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +Emitido quando `webContents` deseja fazer autenticação básica. + +O comportamento padrão é cancelar todas as autenticações, para sobrescrever +isto, você deve impedir esse comportamento com `event.preventDefault()` e +chamar `callback(username, password)` com as credenciais. + +```javascript +app.on('login', function(event, webContents, request, authInfo, callback) { + event.preventDefault(); + callback('username', 'secret'); +}) +``` + +### Evento: 'gpu-process-crashed' + +Emitido quando o processo da gpu falha. + +## Métodos + +O objeto `app` possui os seguintes métodos: + +**Nota:** Alguns métodos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal. + +### `app.quit()` + +Tente fechar todas as janelas. O evento `before-quit` será emitido primeiro. Se todas +as janelas fecharem com sucesso, o evento `will-quit` será emitido e por padrão o +aplicativo irá terminar. + +Este método garante que todos os manipuladores de evento `beforeunload` e `unload` +sejam corretamente executados. É possível que uma janela cancele o processo de +encerramento ao retornar `false` no manipulador de evento `beforeunload`. + +### `app.exit(exitCode)` + +* `exitCode` Integer + +Finaliza imediatamente com `exitCode`. + +Todas as janelas serão fechadas imediatamente sem perguntar ao usuário, e os eventos +`before-quit` e `will-quit` não serão emitidos. + +### `app.getAppPath()` + +Retorna o atual diretório do aplicativo. + +### `app.getPath(name)` + +* `name` String + +Retorna um endereço para um diretório especial ou arquivo associado com `nome`. +Numa falha um `Error` é lançado. + +Você pode requisitar os seguintes endereços pelo nome: + +* `home` Diretório *home* do usuário. +* `appData` Diretório de dados do aplicativo por usuário, que por padrão aponta para: + * `%APPDATA%` no Windows + * `$XDG_CONFIG_HOME` ou `~/.config` no Linux + * `~/Library/Application Support` no OS X +* `userData` O diretório para guardar os arquivos de configuração do seu aplicativo, que por padrão é o diretório `appData` concatenado com o nome do seu aplicativo. +* `temp` Diretório temporário. +* `exe` O arquivo executável atual. +* `module` A biblioteca `libchromiumcontent`. +* `desktop` O diretório *Desktop* do usuário atual. +* `documents` Diretório "Meus Documentos" do usuário. +* `downloads` Diretório dos downloads do usuário. +* `music` Diretório de músicas do usuário. +* `pictures` Diretório de imagens do usuário. +* `videos` Diretório de vídeos do usuário. + +### `app.setPath(name, path)` + +* `name` String +* `path` String + +Sobrescreve o `path` para um diretório especial ou arquivo associado com `name`. +Se o endereço especifica um diretório não existente, o diretório será criado por +este método. Numa falha um `Error` é lançado. + +Você pode sobrescrever apenas endereços com um `name` definido em `app.getPath`. + +Por padrão, *cookies* e *caches* de páginas web serão guardadas no diretório `userData`. Se você quiser mudar esta localização, você deve sobrescrever o +endereço `userData` antes que o evento `ready` do módulo `app` seja emitido. + +### `app.getVersion()` + +Retorna a versão do aplicativo carregado. Se nenhuma versão for encontrada no +arquivo `package.json` do aplicativo, a versão do pacote ou executável atual é +retornada. + +### `app.getName()` + +Retorna o nome do aplicativo atual, que é o nome no arquivo `package.json` do +aplicativo. + +Normalmente o campo `name` do `package.json` é um nome curto em letras minúsculas, +de acordo com as especificações de módulos npm. Normalmente você deve também +especificar um campo `productName`, que é o nome completo em letras maiúsculas do +seu aplicativo, e que será preferido ao `name` pelo Electron. + +### `app.getLocale()` + +Retorna a localidade atual do aplicativo. + +### `app.addRecentDocument(path)` _OS X_ _Windows_ + +* `path` String + +Adiciona `path` à lista de documentos recentes. + +Esta lista é gerenciada pelo S.O.. No Windows você pode visitar a lista pela +barra de tarefas, e no OS X você pode visita-la pelo *dock*. + +### `app.clearRecentDocuments()` _OS X_ _Windows_ + +Limpa a lista de documentos recentes. + +### `app.setUserTasks(tasks)` _Windows_ + +* `tasks` Array - Vetor de objetos `Task` + +Adiciona `tasks` à categoria [Tasks][tasks] do JumpList no Windows. + +`tasks` é um vetor de objetos `Task` no seguinte formato: + +`Task` Object +* `program` String - Endereço do programa a ser executado, normalmente você deve especificar `process.execPath` que abre o programa atual. +* `arguments` String - Os argumentos de linha de comando quando `program` é executado. +* `title` String - A string a ser exibida em uma JumpList. +* `description` String - Descrição desta *task*. +* `iconPath` String - O endereço absoluto para um ícone a ser exibido em uma JumpList, que pode ser um arquivo arbitrário que contém um ícone. Normalmente você pode especificar `process.execPath` para mostrar o ícone do programa. +* `iconIndex` Integer - O índice do ícone do arquivo do icone. Se um arquivo de ícone consiste de dois ou mais ícones, defina este valor para identificar o ícone. Se o arquivo de ícone consiste de um ícone apenas, este valor é 0. + +### `app.allowNTLMCredentialsForAllDomains(allow)` + +* `allow` Boolean + +Define dinamicamente se sempre envia credenciais para HTTP NTLM ou autenticação *Negotiate* - normalmente, o Electron irá mandar apenas credenciais NTLM/Kerberos para URLs que se enquadram em sites "Intranet Local" (estão no mesmo domínio que você). +Entretanto, esta detecção frequentemente falha quando redes corporativas são mal configuradas, então isso permite optar por esse comportamento e habilitá-lo para todas as URLs. + +### `app.makeSingleInstance(callback)` + +* `callback` Function + +Este método faz da sua aplicação uma Aplicação de Instância Única - invés de permitir múltiplas instâncias do seu aplicativo rodarem, isto irá assegurar que apenas uma única instância do seu aplicativo rodará, e outras instâncias sinalizam esta instância e finalizam. + +`callback` será chamado com `callback(argv, workingDirectory)` quando uma segunda instância tenha sido executada. `argv` é um vetor de argumentos de linha de comando da segunda instância, e `workingDirectory` é o atual endereço de seu diretório. +Normalmente aplicativos respondem à isso não minimizando sua janela primária e dando foco à ela. + +É garantida a execução do `callback` após o evento `ready` do `app` ser emitido. + +Este método retorna `false` caso seu processo seja a instância primária do aplicativo e seu aplicativo deve continuar carregando. E retorna `true` caso seu processo tenha enviado seus parâmetros para outra instância, e você deve imediatamente finalizar. + +No OS X o sistema enforça instância única automaticamente quando usuários tentam abrir uma segunda instância do seu aplicativo no *Finder*, e os eventos `open-file` e `open-url` serão emitidos para isso. Entretanto, quando usuários inicializam seu aplicativo na linha de comando, o mecanismo de instância única do sistema será ignorado e você terá de utilizar esse método para assegurar-se de ter uma instância única. + +Um exemplo de ativação da janela de primeira instância quando uma segunda instância inicializa: + +```js +var myWindow = null; + +var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { + // Alguém tentou rodar uma segunda instância, devemos focar nossa janela + if (myWindow) { + if (myWindow.isMinimized()) myWindow.restore(); + myWindow.focus(); + } + return true; +}); + +if (shouldQuit) { + app.quit(); + return; +} + +// Cria myWindow, carrega o resto do aplicativo, etc... +app.on('ready', function() { +}); +``` + +### `app.setAppUserModelId(id)` _Windows_ + +* `id` String + +Muda o [Application User Model ID][app-user-model-id] para `id`. + +### `app.commandLine.appendSwitch(switch[, value])` + +Adiciona uma opção (com `value` opcional) à linha de comando do Chromium. + +**Nota:** Isto não irá afetar `process.argv`, e é utilizado principalmente por desenvolvedores para controlar alguns comportamentos de baixo nível do Chromium. + +### `app.commandLine.appendArgument(value)` + +Adiciona um argumento à linha de comando do Chromium. O argumento será passado com aspas corretamente. + +**Nota:** Isto não irá afetar `process.argv`. + +### `app.dock.bounce([type])` _OS X_ + +* `type` String (opcional) - Pode ser `critical` ou `informational`. O padrão é + `informational` + +Quando `critical` é passado, o ícone do *dock* irá pular até que o aplicativo se torne ativo ou a requisição seja cancelada. + +Quando `informational` é passado, o ícone do *dock* irá pular por um segundo. +Entretanto, a requisição se mantém ativa até que o aplicativo se torne ativo ou a requisição seja cancelada. + +Retorna um ID representando a requisição. + +### `app.dock.cancelBounce(id)` _OS X_ + +* `id` Integer + +Cancela o salto do `id`. + +### `app.dock.setBadge(text)` _OS X_ + +* `text` String + +Define a string a ser exibida na área de *badging* do *dock*. + +### `app.dock.getBadge()` _OS X_ + +Retorna a string da *badge* do *dock*. + +### `app.dock.hide()` _OS X_ + +Esconde o ícone do *dock*. + +### `app.dock.show()` _OS X_ + +Exibe o ícone do *dock*. + +### `app.dock.setMenu(menu)` _OS X_ + +* `menu` Menu + +Define o [menu do dock][dock-menu] do aplicativo. + +[dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 +[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 7fd1db192b1d0f9da0150e01f34c64bf596eb875 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 30 Nov 2015 18:12:00 -0800 Subject: [PATCH 19/42] Lint harder --- atom/browser/net/url_request_async_asar_job.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index 86d92071e..46065259f 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -4,6 +4,8 @@ #include "atom/browser/net/url_request_async_asar_job.h" +#include + namespace atom { URLRequestAsyncAsarJob::URLRequestAsyncAsarJob( From e3ec1fe8abbad5c78dcf785fa64dfc2e10c751dd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 13:09:37 +0800 Subject: [PATCH 20/42] Add process.noAsar to turn off asar support --- atom/common/lib/asar.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index f7eeceb3f..2373385f7 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -18,6 +18,7 @@ process.on 'exit', -> # Separate asar package's path from full path. splitPath = (p) -> + return [false] if process.noAsar # shortcut to disable asar. return [false] if typeof p isnt 'string' return [true, p, ''] if p.substr(-5) is '.asar' p = path.normalize p From 900dc78a47598cec6bbfc0d6220ce69016919e82 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 13:09:50 +0800 Subject: [PATCH 21/42] spec: process.noAsar --- spec/asar-spec.coffee | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index af39fa3ec..b7a62f8ee 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -423,6 +423,41 @@ describe 'asar package', -> p = path.join fixtures, 'asar', 'unpack.asar', 'a.txt' assert.equal internalModuleReadFile(p).toString().trim(), 'a' + describe 'process.noAsar', -> + beforeEach -> + process.noAsar = true + afterEach -> + process.noAsar = false + + it 'disables asar support in sync API', -> + file = path.join fixtures, 'asar', 'a.asar', 'file1' + dir = path.join fixtures, 'asar', 'a.asar', 'dir1' + assert.throws (-> fs.readFileSync file), /ENOTDIR/ + assert.throws (-> fs.lstatSync file), /ENOTDIR/ + assert.throws (-> fs.realpathSync file), /ENOTDIR/ + assert.throws (-> fs.readdirSync dir), /ENOTDIR/ + + it 'disables asar support in async API', (done) -> + file = path.join fixtures, 'asar', 'a.asar', 'file1' + dir = path.join fixtures, 'asar', 'a.asar', 'dir1' + fs.readFile file, (error) -> + assert.equal error.code, 'ENOTDIR' + fs.lstat file, (error) -> + assert.equal error.code, 'ENOTDIR' + fs.realpath file, (error) -> + assert.equal error.code, 'ENOTDIR' + fs.readdir dir, (error) -> + assert.equal error.code, 'ENOTDIR' + done() + + it 'treats *.asar as normal file', -> + originalFs = require 'original-fs' + asar = path.join fixtures, 'asar', 'a.asar' + content1 = fs.readFileSync asar + content2 = originalFs.readFileSync asar + assert.equal content1.compare(content2), 0 + assert.throws (-> fs.readdirSync asar), /ENOTDIR/ + describe 'asar protocol', -> url = require 'url' From 165b464a1503e8a03e761e8a0549848724b2b699 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 13:43:52 +0800 Subject: [PATCH 22/42] docs: process.noAsar --- docs/api/process.md | 9 ++++++++- docs/tutorial/application-packaging.md | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/api/process.md b/docs/api/process.md index 22fe452b0..620ad6dc9 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -31,11 +31,18 @@ process.once('loaded', function() { }); ``` +## Properties + +### `process.noAsar` + +Setting this to `true` can disable the support for `asar` archives in Node's +built-in modules. + ## Methods The `process` object has the following method: -### `process.hang` +### `process.hang()` Causes the main thread of the current process hang. diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index c6e0ae3c4..b42a2f929 100644 --- a/docs/tutorial/application-packaging.md +++ b/docs/tutorial/application-packaging.md @@ -103,6 +103,14 @@ var originalFs = require('original-fs'); originalFs.readFileSync('/path/to/example.asar'); ``` +You can also set `process.noAsar` to `true` to disable the support for `asar` in +the `fs` module: + +```javascript +process.noAsar = true; +fs.readFileSync('/path/to/example.asar'); +``` + ## Limitations on Node API Even though we tried hard to make `asar` archives in the Node API work like From 0f17a0163d16f8cdc2a032ebd96a3034525c0271 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 16:21:15 +0800 Subject: [PATCH 23/42] Put common constants in atom_constants --- atom/browser/net/js_asker.cc | 2 -- atom/browser/net/js_asker.h | 3 --- atom/browser/net/url_request_async_asar_job.cc | 5 +++-- atom/browser/net/url_request_buffer_job.cc | 3 ++- atom/browser/net/url_request_string_job.cc | 3 ++- atom/common/atom_constants.cc | 11 +++++++++++ atom/common/atom_constants.h | 15 +++++++++++++++ filenames.gypi | 2 ++ 8 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 atom/common/atom_constants.cc create mode 100644 atom/common/atom_constants.h diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index 0e232feff..8f0d1d2b9 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -11,8 +11,6 @@ namespace atom { -const std::string kCorsHeader("Access-Control-Allow-Origin: *"); - namespace internal { namespace { diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index b353b98fa..8ec245ee8 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -5,8 +5,6 @@ #ifndef ATOM_BROWSER_NET_JS_ASKER_H_ #define ATOM_BROWSER_NET_JS_ASKER_H_ -#include - #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -19,7 +17,6 @@ #include "v8/include/v8.h" namespace atom { -extern const std::string kCorsHeader; using JavaScriptHandler = base::Callback)>; diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index 46065259f..3578f3b79 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -6,6 +6,8 @@ #include +#include "atom/common/atom_constants.h" + namespace atom { URLRequestAsyncAsarJob::URLRequestAsyncAsarJob( @@ -36,12 +38,11 @@ void URLRequestAsyncAsarJob::StartAsync(scoped_ptr options) { } } - void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); - headers->AddHeader(kCorsHeader); + headers->AddHeader(kCORSHeader); info->headers = headers; } diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index 55603e77e..aa273bf81 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -6,6 +6,7 @@ #include +#include "atom/common/atom_constants.h" #include "base/strings/string_number_conversions.h" #include "net/base/net_errors.h" @@ -50,7 +51,7 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) { status.append("\0\0", 2); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); - headers->AddHeader(kCorsHeader); + headers->AddHeader(kCORSHeader); if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index 6a12026b2..606781142 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -6,6 +6,7 @@ #include +#include "atom/common/atom_constants.h" #include "net/base/net_errors.h" namespace atom { @@ -32,7 +33,7 @@ void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); - headers->AddHeader(kCorsHeader); + headers->AddHeader(kCORSHeader); if (!mime_type_.empty()) { std::string content_type_header(net::HttpRequestHeaders::kContentType); diff --git a/atom/common/atom_constants.cc b/atom/common/atom_constants.cc new file mode 100644 index 000000000..dacda3c81 --- /dev/null +++ b/atom/common/atom_constants.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/atom_constants.h" + +namespace atom { + +const char* kCORSHeader = "Access-Control-Allow-Origin: *"; + +} // namespace atom diff --git a/atom/common/atom_constants.h b/atom/common/atom_constants.h new file mode 100644 index 000000000..e0d42e83e --- /dev/null +++ b/atom/common/atom_constants.h @@ -0,0 +1,15 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_ATOM_CONSTANTS_H_ +#define ATOM_COMMON_ATOM_CONSTANTS_H_ + +namespace atom { + +// Header to ignore CORS. +extern const char* kCORSHeader; + +} // namespace atom + +#endif // ATOM_COMMON_ATOM_CONSTANTS_H_ diff --git a/filenames.gypi b/filenames.gypi index 715707917..151a69ff1 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -286,6 +286,8 @@ 'atom/common/asar/scoped_temporary_file.h', 'atom/common/atom_command_line.cc', 'atom/common/atom_command_line.h', + 'atom/common/atom_constants.cc', + 'atom/common/atom_constants.h', 'atom/common/common_message_generator.cc', 'atom/common/common_message_generator.h', 'atom/common/crash_reporter/crash_reporter.cc', From 1b3eb1cc5df74ed2dac3f8e7e0fea17497ddda28 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 16:55:52 +0800 Subject: [PATCH 24/42] Delay the did-fail-provisional-load event to next tick Chrome is doing some stuff after the DidFailProvisionalLoad event, if we call LoadURL at this time crash would happen. --- atom/browser/api/atom_api_web_contents.cc | 5 ++--- atom/browser/api/lib/web-contents.coffee | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 066ca9cc7..339be85fe 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -460,14 +460,13 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, Emit("did-finish-load"); } -// this error occurs when host could not be found void WebContents::DidFailProvisionalLoad( content::RenderFrameHost* render_frame_host, - const GURL& validated_url, + const GURL& url, int error_code, const base::string16& error_description, bool was_ignored_by_handler) { - Emit("did-fail-load", error_code, error_description, validated_url); + Emit("did-fail-provisional-load", error_code, error_description, url); } void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host, diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 335928dce..45545fe24 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -70,6 +70,12 @@ wrapWebContents = (webContents) -> menu = Menu.buildFromTemplate params.menu menu.popup params.x, params.y + # This error occurs when host could not be found. + webContents.on 'did-fail-provisional-load', (args...) -> + # Calling loadURL during this event might cause crash, so delay the event + # until next tick. + setImmediate => @emit 'did-fail-load', args... + # Deprecated. deprecate.rename webContents, 'loadUrl', 'loadURL' deprecate.rename webContents, 'getUrl', 'getURL' From 8d20dda6d77370b962eddae38e4fa0c42bad08ba Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 17:51:09 +0800 Subject: [PATCH 25/42] No need to override TitleWasSet in NativeWindow --- atom/browser/api/atom_api_window.cc | 5 ----- atom/browser/api/atom_api_window.h | 2 -- atom/browser/api/lib/browser-window.coffee | 5 +++++ atom/browser/native_window.cc | 11 ----------- atom/browser/native_window.h | 1 - atom/browser/native_window_observer.h | 4 ---- 6 files changed, 5 insertions(+), 23 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index a5aa4a126..569640554 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -161,11 +161,6 @@ Window::~Window() { Destroy(); } -void Window::OnPageTitleUpdated(bool* prevent_default, - const std::string& title) { - *prevent_default = Emit("page-title-updated", title); -} - void Window::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 757abd205..a04e00cfb 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -54,8 +54,6 @@ class Window : public mate::TrackableObject, virtual ~Window(); // NativeWindowObserver: - void OnPageTitleUpdated(bool* prevent_default, - const std::string& title) override; void WillCloseWindow(bool* prevent_default) override; void OnWindowClosed() override; void OnWindowBlur() override; diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index d693a6d93..84c769086 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -31,6 +31,11 @@ BrowserWindow::_init = -> @webContents.on 'crashed', => @emit 'crashed' + # Change window title to page title. + @webContents.on 'page-title-set', (event, title, explicitSet) => + @emit 'page-title-updated', event, title + @setTitle title unless event.defaultPrevented + # Sometimes the webContents doesn't get focus when window is shown, so we have # to force focusing on webContents in this case. The safest way is to focus it # when we first start to load URL, if we do it earlier it won't have effect, diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index ad7a6c4b0..a3df240e4 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -505,17 +505,6 @@ void NativeWindow::BeforeUnloadDialogCancelled() { window_unresposive_closure_.Cancel(); } -void NativeWindow::TitleWasSet(content::NavigationEntry* entry, - bool explicit_set) { - bool prevent_default = false; - std::string text = entry ? base::UTF16ToUTF8(entry->GetTitle()) : ""; - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - OnPageTitleUpdated(&prevent_default, text)); - if (!prevent_default && !is_closed_) - SetTitle(text); -} - bool NativeWindow::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(NativeWindow, message) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index e32b94811..0c918d92d 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -262,7 +262,6 @@ class NativeWindow : public base::SupportsUserData, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void BeforeUnloadDialogCancelled() override; - void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; private: diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 54004a300..ce2d41c6f 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -21,10 +21,6 @@ class NativeWindowObserver { public: virtual ~NativeWindowObserver() {} - // Called when the web page of the window has updated it's document title. - virtual void OnPageTitleUpdated(bool* prevent_default, - const std::string& title) {} - // Called when the web page in window wants to create a popup window. virtual void WillCreatePopupWindow(const base::string16& frame_name, const GURL& target_url, From 83ee78451ad9d861deb0f14634f6c3fc2300e5d1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 17:52:13 +0800 Subject: [PATCH 26/42] Emit event when title becomes empty --- atom/browser/api/atom_api_web_contents.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 339be85fe..0c8a5ff3d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -519,9 +519,10 @@ void WebContents::DidNavigateMainFrame( void WebContents::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { - // Back/Forward navigation may have pruned entries. if (entry) Emit("page-title-set", entry->GetTitle(), explicit_set); + else + Emit("page-title-set", "", explicit_set); } void WebContents::DidUpdateFaviconURL( From c95117fb227f438b8dc622f124fb9096f6a915ed Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 18:34:58 +0800 Subject: [PATCH 27/42] Delay the page-title-set event to next tick --- atom/browser/api/atom_api_web_contents.cc | 4 ++-- atom/browser/api/lib/web-contents.coffee | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0c8a5ff3d..b12b3fea2 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -520,9 +520,9 @@ void WebContents::DidNavigateMainFrame( void WebContents::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { if (entry) - Emit("page-title-set", entry->GetTitle(), explicit_set); + Emit("-page-title-set", entry->GetTitle(), explicit_set); else - Emit("page-title-set", "", explicit_set); + Emit("-page-title-set", "", explicit_set); } void WebContents::DidUpdateFaviconURL( diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 45545fe24..dbc9a15fc 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -76,6 +76,10 @@ wrapWebContents = (webContents) -> # until next tick. setImmediate => @emit 'did-fail-load', args... + # Delays the page-title-set event to next tick. + webContents.on '-page-title-set', (args...) -> + setImmediate => @emit 'page-title-set', args... + # Deprecated. deprecate.rename webContents, 'loadUrl', 'loadURL' deprecate.rename webContents, 'getUrl', 'getURL' From e5974e44ed5584db59eac5318b5d0b2dbd1dba7e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 1 Dec 2015 18:50:56 +0800 Subject: [PATCH 28/42] Deprecate the page-title-set event We have two names for the same event, page-title-updated wins. --- atom/browser/api/atom_api_web_contents.cc | 4 ++-- atom/browser/api/lib/browser-window.coffee | 2 +- atom/browser/api/lib/web-contents.coffee | 8 +++++--- atom/browser/lib/guest-view-manager.coffee | 2 +- .../lib/web-view/guest-view-internal.coffee | 20 +++++++++++-------- docs/api/web-view-tag.md | 6 +++--- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b12b3fea2..f377e8fda 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -520,9 +520,9 @@ void WebContents::DidNavigateMainFrame( void WebContents::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { if (entry) - Emit("-page-title-set", entry->GetTitle(), explicit_set); + Emit("-page-title-updated", entry->GetTitle(), explicit_set); else - Emit("-page-title-set", "", explicit_set); + Emit("-page-title-updated", "", explicit_set); } void WebContents::DidUpdateFaviconURL( diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 84c769086..07b4191d7 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -32,7 +32,7 @@ BrowserWindow::_init = -> @emit 'crashed' # Change window title to page title. - @webContents.on 'page-title-set', (event, title, explicitSet) => + @webContents.on 'page-title-updated', (event, title, explicitSet) => @emit 'page-title-updated', event, title @setTitle title unless event.defaultPrevented diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index dbc9a15fc..dacbc919d 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -76,13 +76,15 @@ wrapWebContents = (webContents) -> # until next tick. setImmediate => @emit 'did-fail-load', args... - # Delays the page-title-set event to next tick. - webContents.on '-page-title-set', (args...) -> - setImmediate => @emit 'page-title-set', args... + # Delays the page-title-updated event to next tick. + webContents.on '-page-title-updated', (args...) -> + setImmediate => @emit 'page-title-updated', args... # Deprecated. deprecate.rename webContents, 'loadUrl', 'loadURL' deprecate.rename webContents, 'getUrl', 'getURL' + deprecate.event webContents, 'page-title-set', 'page-title-updated', (args...) -> + @emit 'page-title-set', args... webContents.printToPDF = (options, callback) -> printingSetting = diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index e6be05a90..d4bf55158 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -19,7 +19,7 @@ supportedWebViewEvents = [ 'gpu-crashed' 'plugin-crashed' 'destroyed' - 'page-title-set' + 'page-title-updated' 'page-favicon-updated' 'enter-html-full-screen' 'leave-html-full-screen' diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 61a93d8cb..b28fec23e 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -21,23 +21,27 @@ WEB_VIEW_EVENTS = 'gpu-crashed': [] 'plugin-crashed': ['name', 'version'] 'destroyed': [] - 'page-title-set': ['title', 'explicitSet'] + 'page-title-updated': ['title', 'explicitSet'] 'page-favicon-updated': ['favicons'] 'enter-html-full-screen': [] 'leave-html-full-screen': [] -dispatchEvent = (webView, event, args...) -> - throw new Error("Unknown event #{event}") unless WEB_VIEW_EVENTS[event]? - domEvent = new Event(event) - for f, i in WEB_VIEW_EVENTS[event] +DEPRECATED_EVENTS = + 'page-title-updated': 'page-title-set' + +dispatchEvent = (webView, eventName, eventKey, args...) -> + if DEPRECATED_EVENTS[eventName]? + dispatchEvent webView, DEPRECATED_EVENTS[eventName], eventKey, args... + domEvent = new Event(eventName) + for f, i in WEB_VIEW_EVENTS[eventKey] domEvent[f] = args[i] webView.dispatchEvent domEvent - webView.onLoadCommit domEvent if event == 'load-commit' + webView.onLoadCommit domEvent if eventName is 'load-commit' module.exports = registerEvents: (webView, viewInstanceId) -> - ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, domEvent, args...) -> - dispatchEvent webView, domEvent, args... + ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, eventName, args...) -> + dispatchEvent webView, eventName, eventName, args... ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (event, channel, args...) -> domEvent = new Event('ipc-message') diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 47a3050a0..56909a52e 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -452,15 +452,15 @@ Fired when a redirect was received while requesting a resource. Fired when document in the given frame is loaded. -### Event: 'page-title-set' +### Event: 'page-title-updated' Returns: * `title` String * `explicitSet` Boolean -Fired when page title is set during navigation. `explicitSet` is false when title is synthesised from file -url. +Fired when page title is set during navigation. `explicitSet` is false when +title is synthesised from file url. ### Event: 'page-favicon-updated' From a99c193cf2d783308a0777e6c6ee606590bfa263 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 1 Dec 2015 11:57:32 -0400 Subject: [PATCH 29/42] :checkered_flag: Preserve file extension when extracting from asar Currently, when calling `copyFileOut`, the original extension from the file is lost, and a generic `*.tmp` is added instead. This becomes problematic in the scenario where we use `child_process.execFile` on a Windows Batch script that lives inside the `asar` package. Windows relies on the extension being present in order to interpret the script accordingly, which results in the following bug because the operating system doesn't know what do to with this `*.tmp` file: ``` Error: spawn UNKNOWN ``` Steps to reproduce: 1. Create a dummy batch script (test.bat): ``` @echo off echo "Hello world" ``` 2. Create an electron app that attemps to call this script with `child_process.execFile`: ```js var child_process = require('child_process'); var path = require('path'); child_process.execFile(path.join(__dirname, 'test.bat'), function(error, stdout) { if (error) throw error; console.log(stdout); }); ``` 3. Package this small application as an asar archive: ```sh > asar pack mytestapp app.asar ``` 4. Execute the application: ```sh > electron.exe app.asar ``` --- atom/common/asar/archive.cc | 3 ++- atom/common/asar/scoped_temporary_file.cc | 14 +++++++++++--- atom/common/asar/scoped_temporary_file.h | 8 +++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index ab93e301b..ebb80cc2c 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -272,7 +272,8 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { } scoped_ptr temp_file(new ScopedTemporaryFile); - if (!temp_file->InitFromFile(&file_, info.offset, info.size)) + base::FilePath::StringType ext = path.Extension(); + if (!temp_file->InitFromFile(&file_, ext, info.offset, info.size)) return false; #if defined(OS_POSIX) diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 6fccc9434..2cc51991e 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -28,20 +28,28 @@ ScopedTemporaryFile::~ScopedTemporaryFile() { } } -bool ScopedTemporaryFile::Init() { +bool ScopedTemporaryFile::Init(const base::FilePath::StringType ext) { if (!path_.empty()) return true; base::ThreadRestrictions::ScopedAllowIO allow_io; - return base::CreateTemporaryFile(&path_); + + base::FilePath temporaryPath_; + if (!base::CreateTemporaryFile(&temporaryPath_)) { + return false; + } + + path_ = temporaryPath_.AddExtension(ext); + return base::Move(temporaryPath_, path_); } bool ScopedTemporaryFile::InitFromFile(base::File* src, + const base::FilePath::StringType ext, uint64 offset, uint64 size) { if (!src->IsValid()) return false; - if (!Init()) + if (!Init(ext)) return false; std::vector buf(size); diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index ffaee22e5..c0804a4e6 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -22,11 +22,13 @@ class ScopedTemporaryFile { ScopedTemporaryFile(); virtual ~ScopedTemporaryFile(); - // Init an empty temporary file. - bool Init(); + // Init an empty temporary file with a certain extension. + bool Init(const base::FilePath::StringType ext); // Init an temporary file and fill it with content of |path|. - bool InitFromFile(base::File* src, uint64 offset, uint64 size); + bool InitFromFile(base::File* src, + const base::FilePath::StringType ext, + uint64 offset, uint64 size); base::FilePath path() const { return path_; } From 1b1c4bec4e4634087bb17fb96a8e60098329dabc Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Tue, 1 Dec 2015 21:09:20 -0200 Subject: [PATCH 30/42] :memo: [ci skip] Add translation to auto-updater, change links --- docs-translations/pt-BR/README.md | 4 +- docs-translations/pt-BR/api/auto-updater.md | 85 +++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 docs-translations/pt-BR/api/auto-updater.md diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md index 61202f8ca..f458e51da 100644 --- a/docs-translations/pt-BR/README.md +++ b/docs-translations/pt-BR/README.md @@ -40,8 +40,8 @@ selecione a *tag* que corresponde à sua versão. ### Módulos para o Processo Principal: -* [app](../../docs/api/app.md) -* [autoUpdater](../../docs/api/auto-updater.md) +* [app](api/app.md) +* [autoUpdater](api/auto-updater.md) * [BrowserWindow](../../docs/api/browser-window.md) * [contentTracing](../../docs/api/content-tracing.md) * [dialog](../../docs/api/dialog.md) diff --git a/docs-translations/pt-BR/api/auto-updater.md b/docs-translations/pt-BR/api/auto-updater.md new file mode 100644 index 000000000..1c27a4b77 --- /dev/null +++ b/docs-translations/pt-BR/api/auto-updater.md @@ -0,0 +1,85 @@ +# autoUpdater + +Este módulo oferece uma interface para o framework de atualização automática `Squirrel`. + +## Notificações de Plataforma + +Embora o `autoUpdater` ofereça uma API uniforme para diferentes plataformas, existem diferenças sutis em cada plataforma. + +### OS X + +No OS X, o módulo `autoUpdater` é construído sobre o [Squirrel.Mac][squirrel-mac], o que significa que você não precisa de nenhuma configuração especial para fazê-lo funcionar. Para requerimentos de servidor, você pode ler [Server Support][server-support]. + +### Windows + +No Windows, você deve instalar seu aplicativo na máquina de um usuário antes que possa usar o auto-updater, então é recomendado utilizar o módulo [grunt-electron-installer][installer] para gerar um instalador do Windows. + +O instalador gerado com Squirrel irá criar um ícone de atalho com um [Application User Model ID][app-user-model-id] no formato `com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, por exemplo: `com.squirrel.slack.Slack` e `com.squirrel.code.Code`. Você precisa usar o mesmo ID para seu aplicativo a API `app.setAppUserModelId`, senão o Windows não conseguirá fixar seu aplicativo corretamente na barra de tarefas. + +A configuração do servidor também é diferente do OS X. Você pode ler a documentação do [Squirrel.Windows][squirrel-windows] para mais detalhes. + +### Linux + +Não há suporte nativo do auto-updater para Linux, então é recomendado utilizar o gerenciador de pacotes da distribuição para atualizar seu aplicativo. + +## Eventos + +O objeto `autoUpdater` emite os seguintes eventos: + +### Evento: 'error' + +Retorna: + +* `error` Error + +Emitido quando há um erro durante a atualização. + +### Evento: 'checking-for-update' + +Emitido quando está verificando se uma atualização foi inicializada. + +### Evento: 'update-available' + +Emitido quando há uma atualização disponível. A autalização é baixada automaticamente. + +### Evento: 'update-not-available' + +Emitido quando não há uma atualização disponível. + +### Evento: 'update-downloaded' + +Retorna: + +* `event` Event +* `releaseNotes` String +* `releaseName` String +* `releaseDate` Date +* `updateURL` String + +Emitido quando uma atualização foi baixada. + +No Windows apenas `releaseName` está disponível. + +## Métodos + +O objeto `autoUpdater` possui os seguintes métodos: + +### `autoUpdater.setFeedURL(url)` + +* `url` String + +Define a `url` e inicializa o auto-updater. A `url` não pode ser alterada uma vez que foi definida. + +### `autoUpdater.checkForUpdates()` + +Pergunta ao servidor se há uma atualização. Você deve chamar `setFeedURL` antes de usar esta API. + +### `autoUpdater.quitAndInstall()` + +Reinicia o aplicativo e instala a atualização após esta ter sido baixada. Só deve ser chamado após o `update-downloaded` ter sido emitido. + +[squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac +[server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support +[squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows +[installer]: https://github.com/atom/grunt-electron-installer +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 229dc02a41b06f47285746f6de3350795d36e8f3 Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Tue, 1 Dec 2015 21:34:35 -0200 Subject: [PATCH 31/42] :memo: [ci skip] Update to match english docs, fix typos --- docs-translations/pt-BR/api/process.md | 40 +++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/docs-translations/pt-BR/api/process.md b/docs-translations/pt-BR/api/process.md index 3da0dc583..1c20e2df1 100644 --- a/docs-translations/pt-BR/api/process.md +++ b/docs-translations/pt-BR/api/process.md @@ -1,22 +1,48 @@ # process -O objeto `process` no Electron tem as seguintes diferenças de um upstream node: +O objeto `process` no Electron tem as seguintes diferenças do objeto no upstream node: -* `process.type` String - Tipo de processo, pode ser `browser` (i.e. main process) +* `process.type` String - Tipo de processo, pode ser `browser` (processo principal) ou `renderer`. * `process.versions['electron']` String - Versão do Electron. * `process.versions['chrome']` String - Versão do Chromium. -* `process.resourcesPath` String - Caminho para os códigos fontes JavaScript. +* `process.resourcesPath` String - Caminho para o código fonte JavaScript. +* `process.mas` Boolean - Para build da Mac App Store, este valor é `true`, para outros builds é `undefined`. + +## Eventos + +### Evento: 'loaded' + +Emitido quando o Electron carregou seu script de inicialização interno e está começando a carregar a página web ou o script principal. + +Pode ser utilizado pelo script pré-carregamento (preload.js abaixo) para adicionar símbolos globais do Node removidos para o escopo global quando a integração do node é desligada: + +```js +// preload.js +var _setImmediate = setImmediate; +var _clearImmediate = clearImmediate; +process.once('loaded', function() { + global.setImmediate = _setImmediate; + global.clearImmediate = _clearImmediate; +}); +``` + +## Propriedades + +### `process.noAsar` + +Definir isto para `true` pode desabilitar o suporte para arquivos `asar` nos módulos nativos do Node. # Métodos -O objeto `process` tem os seguintes método: + +O objeto `process` tem os seguintes métodos: ### `process.hang` -Afeta a thread principal do processo atual. +Faz com que o *thread* principal do processo congele. -## process.setFdLimit(MaxDescritores) _OS X_ _Linux_ +### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_ * `maxDescriptors` Integer Define o limite do arquivo descritor para `maxDescriptors` ou para o limite do OS, -o que for menor para o processo atual. \ No newline at end of file +o que for menor para o processo atual. From d76e21853b6a35552dec7d933dbf8e9aa4cfebeb Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Tue, 1 Dec 2015 21:38:25 -0200 Subject: [PATCH 32/42] Change header --- docs-translations/pt-BR/api/auto-updater.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/pt-BR/api/auto-updater.md b/docs-translations/pt-BR/api/auto-updater.md index 1c27a4b77..27c3ef3c0 100644 --- a/docs-translations/pt-BR/api/auto-updater.md +++ b/docs-translations/pt-BR/api/auto-updater.md @@ -2,7 +2,7 @@ Este módulo oferece uma interface para o framework de atualização automática `Squirrel`. -## Notificações de Plataforma +## Avisos sobre Plataformas Embora o `autoUpdater` ofereça uma API uniforme para diferentes plataformas, existem diferenças sutis em cada plataforma. From 9a93ecc3cfe74f6d953751dfc75059fcb81b9feb Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Tue, 1 Dec 2015 21:46:13 -0200 Subject: [PATCH 33/42] :memo: [ci skip] fix typos --- docs-translations/pt-BR/api/accelerator.md | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs-translations/pt-BR/api/accelerator.md b/docs-translations/pt-BR/api/accelerator.md index 87987258b..92d70c844 100644 --- a/docs-translations/pt-BR/api/accelerator.md +++ b/docs-translations/pt-BR/api/accelerator.md @@ -1,7 +1,7 @@ # Acelerador (teclas de atalhos) -Um acelerador é uma string que representa um atalho de tecla. Isso pode conter -multiplos modificadores e códigos chaves, combinado pelo caracter `+`. +Um acelerador é uma string que representa um atalho de tecla. Ele pode conter +múltiplos modificadores e códigos chaves, combinados pelo caractere `+`. Exemplos: @@ -11,13 +11,13 @@ Exemplos: ## Aviso sobre plataformas No Linux e no Windows a tecla `Command` não tem nenhum efeito, -então use `CommandOrControl` que representa a tecla `Command` existente no OSX e +então use `CommandOrControl` que representa a tecla `Command` existente no OS X e `Control` no Linux e no Windows para definir aceleradores (atalhos). A chave `Super` está mapeada para a tecla `Windows` para Windows e Linux, -e para a tecla `Cmd` para OSX. +e para a tecla `Cmd` para OS X. -## Modificadores disponiveis +## Modificadores disponíveis * `Command` (ou `Cmd` abreviado) * `Control` (ou `Ctrl` abreviado) @@ -26,21 +26,21 @@ e para a tecla `Cmd` para OSX. * `Shift` * `Super` -## Códigos chaves disponiveis +## Códigos chaves disponíveis -* `0` to `9` -* `A` to `Z` -* `F1` to `F24` -* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. +* `0` até `9` +* `A` até `Z` +* `F1` até `F24` +* Pontuações como `~`, `!`, `@`, `#`, `$`, etc. * `Plus` * `Space` * `Backspace` * `Delete` * `Insert` -* `Return` (or `Enter` as alias) -* `Up`, `Down`, `Left` and `Right` -* `Home` and `End` -* `PageUp` and `PageDown` -* `Escape` (or `Esc` for short) -* `VolumeUp`, `VolumeDown` and `VolumeMute` -* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause` \ No newline at end of file +* `Return` (ou `Enter` como pseudônimo) +* `Up`, `Down`, `Left` e `Right` +* `Home` e `End` +* `PageUp` e `PageDown` +* `Escape` (ou `Esc` abreviado) +* `VolumeUp`, `VolumeDown` e `VolumeMute` +* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` e `MediaPlayPause` From 5cae8397ccaf6116be4606dc81da498fa529bc9d Mon Sep 17 00:00:00 2001 From: Artur de Oliveira Tsuda Date: Tue, 1 Dec 2015 21:57:07 -0200 Subject: [PATCH 34/42] :memo: [ci skip] fix more typos --- docs-translations/pt-BR/api/shell.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs-translations/pt-BR/api/shell.md b/docs-translations/pt-BR/api/shell.md index 7c3f24ade..65e0a2d42 100644 --- a/docs-translations/pt-BR/api/shell.md +++ b/docs-translations/pt-BR/api/shell.md @@ -1,11 +1,11 @@ # shell -O módulo `shell` fornece funções relacionadas intereções com o OS do usuário. +O módulo `shell` fornece funções relacionadas à integração com o desktop. Um exemplo para abrir uma URL no browser padrão do usuário: ```javascript -var shell = require('shell'); +const shell = require('shell'); shell.openExternal('https://github.com'); ``` @@ -17,26 +17,26 @@ O módulo `shell` tem os seguintes métodos: * `fullPath` String -Exibe o arquivo no gerenciador de arquivos padrão do sistema. Se possivel, seleciona o arquivo automaticamente. +Exibe o arquivo num gerenciador de arquivos. Se possivel, seleciona o arquivo. ### `shell.openItem(fullPath)` * `fullPath` String -Abre o arquivo em seu programa padrão. +Abre o arquivo de maneira padrão do desktop. ### `shell.openExternal(url)` * `url` String -Abre o arquivo seguido de um protocol em seu programa padrão. (Por -exemplo, mailto:foo@bar.com.) +Abre a URL de protocolo externo de maneira padrão do desktop. (Por +exemplo, mailto: URLs no programa de email padrão do usuário) ### `shell.moveItemToTrash(fullPath)` * `fullPath` String -Move o arquivo para a lixeira e retorna um boolean com o resultado da operação. +Move o arquivo para a lixeira e retorna um status boolean com o resultado da operação. ### `shell.beep()` From c691094aa103ee7d036ba524623edd280371dc72 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 11:00:28 +0800 Subject: [PATCH 35/42] spec: Fix failing tests on win32 --- spec/asar-spec.coffee | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index b7a62f8ee..495d89734 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -424,6 +424,8 @@ describe 'asar package', -> assert.equal internalModuleReadFile(p).toString().trim(), 'a' describe 'process.noAsar', -> + errorName = if process.platform is 'win32' then 'ENOENT' else 'ENOTDIR' + beforeEach -> process.noAsar = true afterEach -> @@ -432,22 +434,22 @@ describe 'asar package', -> it 'disables asar support in sync API', -> file = path.join fixtures, 'asar', 'a.asar', 'file1' dir = path.join fixtures, 'asar', 'a.asar', 'dir1' - assert.throws (-> fs.readFileSync file), /ENOTDIR/ - assert.throws (-> fs.lstatSync file), /ENOTDIR/ - assert.throws (-> fs.realpathSync file), /ENOTDIR/ - assert.throws (-> fs.readdirSync dir), /ENOTDIR/ + assert.throws (-> fs.readFileSync file), new RegExp(errorName) + assert.throws (-> fs.lstatSync file), new RegExp(errorName) + assert.throws (-> fs.realpathSync file), new RegExp(errorName) + assert.throws (-> fs.readdirSync dir), new RegExp(errorName) it 'disables asar support in async API', (done) -> file = path.join fixtures, 'asar', 'a.asar', 'file1' dir = path.join fixtures, 'asar', 'a.asar', 'dir1' fs.readFile file, (error) -> - assert.equal error.code, 'ENOTDIR' + assert.equal error.code, errorName fs.lstat file, (error) -> - assert.equal error.code, 'ENOTDIR' + assert.equal error.code, errorName fs.realpath file, (error) -> - assert.equal error.code, 'ENOTDIR' + assert.equal error.code, errorName fs.readdir dir, (error) -> - assert.equal error.code, 'ENOTDIR' + assert.equal error.code, errorName done() it 'treats *.asar as normal file', -> From c3645e3f9532f71fea15dd5c6dad603954978afe Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 11:04:47 +0800 Subject: [PATCH 36/42] Don't call Move if there is no need to move --- atom/common/asar/scoped_temporary_file.cc | 17 ++++++++++------- atom/common/asar/scoped_temporary_file.h | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 2cc51991e..14f2ba8ef 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -28,23 +28,26 @@ ScopedTemporaryFile::~ScopedTemporaryFile() { } } -bool ScopedTemporaryFile::Init(const base::FilePath::StringType ext) { +bool ScopedTemporaryFile::Init(const base::FilePath::StringType& ext) { if (!path_.empty()) return true; base::ThreadRestrictions::ScopedAllowIO allow_io; - base::FilePath temporaryPath_; - if (!base::CreateTemporaryFile(&temporaryPath_)) { + base::FilePath temp_path; + if (!base::CreateTemporaryFile(&temp_path)) return false; - } - path_ = temporaryPath_.AddExtension(ext); - return base::Move(temporaryPath_, path_); + if (ext.empty()) + return true; + + // Keep the original extension. + path_ = temp_path.AddExtension(ext); + return base::Move(temp_path, path_); } bool ScopedTemporaryFile::InitFromFile(base::File* src, - const base::FilePath::StringType ext, + const base::FilePath::StringType& ext, uint64 offset, uint64 size) { if (!src->IsValid()) return false; diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index c0804a4e6..23660a239 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -23,11 +23,11 @@ class ScopedTemporaryFile { virtual ~ScopedTemporaryFile(); // Init an empty temporary file with a certain extension. - bool Init(const base::FilePath::StringType ext); + bool Init(const base::FilePath::StringType& ext); // Init an temporary file and fill it with content of |path|. bool InitFromFile(base::File* src, - const base::FilePath::StringType ext, + const base::FilePath::StringType& ext, uint64 offset, uint64 size); base::FilePath path() const { return path_; } From c493bec0898b2cdc3ae20b2d41b19cdf3041f599 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 11:36:29 +0800 Subject: [PATCH 37/42] Make sure temp file will be cleaned up when base::Move fails --- atom/common/asar/scoped_temporary_file.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 14f2ba8ef..6dd12782d 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -33,17 +33,20 @@ bool ScopedTemporaryFile::Init(const base::FilePath::StringType& ext) { return true; base::ThreadRestrictions::ScopedAllowIO allow_io; - - base::FilePath temp_path; - if (!base::CreateTemporaryFile(&temp_path)) + if (!base::CreateTemporaryFile(&path_)) return false; - if (ext.empty()) - return true; - +#if defined(OS_WIN) // Keep the original extension. - path_ = temp_path.AddExtension(ext); - return base::Move(temp_path, path_); + if (!ext.empty()) { + base::FilePath new_path = path_.AddExtension(ext); + if (!base::Move(path_, new_path)) + return false; + path_ = new_path; + } +#endif + + return true; } bool ScopedTemporaryFile::InitFromFile(base::File* src, From 202475f5a98cf4530845b80c87cd6c218059dc82 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 17:29:58 +0800 Subject: [PATCH 38/42] Deprecating a property with method of same name causes trouble Close #3511. --- atom/browser/api/lib/app.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 4d1803a02..d0ec41c4d 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -65,7 +65,6 @@ wrapDownloadItem = (downloadItem) -> deprecate.property downloadItem, 'url', 'getURL' deprecate.property downloadItem, 'filename', 'getFilename' deprecate.property downloadItem, 'mimeType', 'getMimeType' - deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture' deprecate.rename downloadItem, 'getUrl', 'getURL' downloadItemBindings._setWrapDownloadItem wrapDownloadItem From 95675996989e9675acd06d3fcc4fa30b615eadfc Mon Sep 17 00:00:00 2001 From: Luke Page Date: Wed, 2 Dec 2015 10:23:21 +0000 Subject: [PATCH 39/42] Update debugging-main-process.md --- docs/tutorial/debugging-main-process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index 38c6e61ff..aa95ae312 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -19,7 +19,7 @@ Like `--debug` but pauses the script on the first line. ## Use node-inspector for Debugging -__Note:__ Electron uses node v0.11.13, which currently doesn't work very well +__Note:__ Electron doesn't currently work very well with node-inspector, and the main process will crash if you inspect the `process` object under node-inspector's console. From 2fba05b5e70e5d71f89c350dd42d096bb0f71016 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 18:43:11 +0800 Subject: [PATCH 40/42] Add `menu` parameter for Tray.popUpContextMenu --- atom/browser/api/atom_api_tray.cc | 4 +++- atom/browser/ui/tray_icon.cc | 3 ++- atom/browser/ui/tray_icon.h | 4 +++- atom/browser/ui/tray_icon_cocoa.h | 3 ++- atom/browser/ui/tray_icon_cocoa.mm | 3 ++- atom/browser/ui/win/notify_icon.cc | 5 +++-- atom/browser/ui/win/notify_icon.h | 3 ++- docs/api/tray.md | 8 ++++++-- 8 files changed, 23 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 5e32657f0..1e1c7c304 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -137,9 +137,11 @@ void Tray::DisplayBalloon(mate::Arguments* args, } void Tray::PopUpContextMenu(mate::Arguments* args) { + Menu* menu = nullptr; + args->GetNext(&menu); gfx::Point pos; args->GetNext(&pos); - tray_icon_->PopUpContextMenu(pos); + tray_icon_->PopUpContextMenu(pos, menu ? menu->model() : nullptr); } void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) { diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index 1696aab27..60923c2ad 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -26,7 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon, const base::string16& contents) { } -void TrayIcon::PopUpContextMenu(const gfx::Point& pos) { +void TrayIcon::PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model) { } void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index bc29acd8a..c80ff08d6 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -47,7 +47,9 @@ class TrayIcon { const base::string16& title, const base::string16& contents); - virtual void PopUpContextMenu(const gfx::Point& pos); + // Popups the menu. + virtual void PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model); // Set the context menu for this icon. virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0; diff --git a/atom/browser/ui/tray_icon_cocoa.h b/atom/browser/ui/tray_icon_cocoa.h index 7781c93a1..59e2241aa 100644 --- a/atom/browser/ui/tray_icon_cocoa.h +++ b/atom/browser/ui/tray_icon_cocoa.h @@ -29,7 +29,8 @@ class TrayIconCocoa : public TrayIcon, void SetToolTip(const std::string& tool_tip) override; void SetTitle(const std::string& title) override; void SetHighlightMode(bool highlight) override; - void PopUpContextMenu(const gfx::Point& pos) override; + void PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model) override; void SetContextMenu(ui::SimpleMenuModel* menu_model) override; protected: diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index e25f8ab5c..5005234ab 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -338,7 +338,8 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) { [status_item_view_ setHighlight:highlight]; } -void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos) { +void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model) { [status_item_view_ popUpContextMenu]; } diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index b2ca4bcee..133ab068d 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -66,7 +66,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, return; } else if (!double_button_click) { // single right click if (menu_model_) - PopUpContextMenu(cursor_pos); + PopUpContextMenu(cursor_pos, menu_model_); else NotifyRightClicked(gfx::Rect(rect), modifiers); } @@ -142,7 +142,8 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, LOG(WARNING) << "Unable to create status tray balloon."; } -void NotifyIcon::PopUpContextMenu(const gfx::Point& pos) { +void NotifyIcon::PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model) { // Returns if context menu isn't set. if (!menu_model_) return; diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index d368dec71..8ee600033 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -52,7 +52,8 @@ class NotifyIcon : public TrayIcon { void DisplayBalloon(const gfx::Image& icon, const base::string16& title, const base::string16& contents) override; - void PopUpContextMenu(const gfx::Point& pos) override; + void PopUpContextMenu(const gfx::Point& pos, + ui::SimpleMenuModel* menu_model) override; void SetContextMenu(ui::SimpleMenuModel* menu_model) override; private: diff --git a/docs/api/tray.md b/docs/api/tray.md index f230c324e..08a43638b 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -187,12 +187,16 @@ when the tray icon is clicked. Defaults to true. Displays a tray balloon. -### `Tray.popUpContextMenu([position])` _OS X_ _Windows_ +### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_ -* `position` Object (optional)- The pop up position. +* `menu` Menu (optional) +* `position` Object (optional) - The pop up position. * `x` Integer * `y` Integer +Popups the context menu of tray icon. When `menu` is passed, the `menu` will +showed instead of the tray's context menu. + The `position` is only available on Windows, and it is (0, 0) by default. ### `Tray.setContextMenu(menu)` From 3cdd0f35c7d501572164a13051c2bb7ea6ac808f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 19:05:22 +0800 Subject: [PATCH 41/42] mac: Implement menu parameter --- atom/browser/api/atom_api_tray.cc | 4 ++-- atom/browser/ui/tray_icon_cocoa.mm | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 1e1c7c304..3b1a3a632 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -137,11 +137,11 @@ void Tray::DisplayBalloon(mate::Arguments* args, } void Tray::PopUpContextMenu(mate::Arguments* args) { - Menu* menu = nullptr; + mate::Handle menu; args->GetNext(&menu); gfx::Point pos; args->GetNext(&pos); - tray_icon_->PopUpContextMenu(pos, menu ? menu->model() : nullptr); + tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model()); } void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) { diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 5005234ab..997ac6fd3 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -23,6 +23,7 @@ const CGFloat kVerticalTitleMargin = 2; atom::TrayIconCocoa* trayIcon_; // weak AtomMenuController* menuController_; // weak BOOL isHighlightEnable_; + BOOL forceHighlight_; BOOL inMouseEventSequence_; base::scoped_nsobject image_; base::scoped_nsobject alternateImage_; @@ -39,6 +40,8 @@ const CGFloat kVerticalTitleMargin = 2; image_.reset([image copy]); trayIcon_ = icon; isHighlightEnable_ = YES; + forceHighlight_ = NO; + inMouseEventSequence_ = NO; if ((self = [super initWithFrame: CGRectZero])) { // Setup the image view. @@ -238,7 +241,19 @@ const CGFloat kVerticalTitleMargin = 2; [self setNeedsDisplay:YES]; } -- (void)popUpContextMenu { +- (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model { + // Show a custom menu. + if (menu_model) { + base::scoped_nsobject menuController( + [[AtomMenuController alloc] initWithModel:menu_model]); + forceHighlight_ = YES; // Should highlight when showing menu. + [self setNeedsDisplay:YES]; + [statusItem_ popUpStatusItemMenu:[menuController menu]]; + forceHighlight_ = NO; + [self setNeedsDisplay:YES]; + return; + } + if (menuController_ && ![menuController_ isMenuOpen]) { // Redraw the dray icon to show highlight if it is enabled. [self setNeedsDisplay:YES]; @@ -288,6 +303,8 @@ const CGFloat kVerticalTitleMargin = 2; } - (BOOL)shouldHighlight { + if (isHighlightEnable_ && forceHighlight_) + return true; BOOL isMenuOpen = menuController_ && [menuController_ isMenuOpen]; return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen); } @@ -340,7 +357,7 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) { void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos, ui::SimpleMenuModel* menu_model) { - [status_item_view_ popUpContextMenu]; + [status_item_view_ popUpContextMenu:menu_model]; } void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) { From 615ce45849db3d0c2db785d3dce8e2450d9e197c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Dec 2015 19:58:10 +0800 Subject: [PATCH 42/42] win: Implement menu parameter --- atom/browser/ui/win/notify_icon.cc | 21 +++++++++++---------- atom/browser/ui/win/notify_icon.h | 3 +-- atom/browser/ui/win/notify_icon_host.cc | 4 ---- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 133ab068d..1ac29f136 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -13,6 +13,7 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/screen.h" #include "ui/views/controls/menu/menu_runner.h" namespace atom { @@ -45,8 +46,7 @@ NotifyIcon::~NotifyIcon() { Shell_NotifyIcon(NIM_DELETE, &icon_data); } -void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, - int modifiers, +void NotifyIcon::HandleClickEvent(int modifiers, bool left_mouse_click, bool double_button_click) { NOTIFYICONIDENTIFIER icon_id; @@ -66,7 +66,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, return; } else if (!double_button_click) { // single right click if (menu_model_) - PopUpContextMenu(cursor_pos, menu_model_); + PopUpContextMenu(gfx::Point(), menu_model_); else NotifyRightClicked(gfx::Rect(rect), modifiers); } @@ -145,22 +145,23 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, void NotifyIcon::PopUpContextMenu(const gfx::Point& pos, ui::SimpleMenuModel* menu_model) { // Returns if context menu isn't set. - if (!menu_model_) + if (!menu_model) return; // Set our window as the foreground window, so the context menu closes when // we click away from it. if (!SetForegroundWindow(window_)) return; + // Show menu at mouse's position by default. + gfx::Rect rect(pos, gfx::Size()); + if (pos.IsOrigin()) + rect.set_origin(gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); + views::MenuRunner menu_runner( - menu_model_, + menu_model, views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS); ignore_result(menu_runner.RunMenuAt( - NULL, - NULL, - gfx::Rect(pos, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_MOUSE)); + NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE)); } void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) { diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 8ee600033..23608c7c7 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -33,8 +33,7 @@ class NotifyIcon : public TrayIcon { // Handles a click event from the user - if |left_button_click| is true and // there is a registered observer, passes the click event to the observer, // otherwise displays the context menu if there is one. - void HandleClickEvent(const gfx::Point& cursor_pos, - int modifiers, + void HandleClickEvent(int modifiers, bool left_button_click, bool double_button_click); diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index 2c84837e7..a0d4287ff 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -15,7 +15,6 @@ #include "base/win/win_util.h" #include "base/win/wrapped_window_proc.h" #include "ui/events/event_constants.h" -#include "ui/gfx/screen.h" #include "ui/gfx/win/hwnd_util.h" namespace atom { @@ -172,10 +171,7 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, case WM_CONTEXTMENU: // Walk our icons, find which one was clicked on, and invoke its // HandleClickEvent() method. - gfx::Point cursor_pos( - gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); win_icon->HandleClickEvent( - cursor_pos, GetKeyboardModifers(), (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK));