From 8bd07af5e579da36140191fbea59f561964fbda3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 16:22:16 -0800 Subject: [PATCH 001/132] Correct typo in comment --- atom/browser/lib/chrome-extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index fbb537d052c1..eaed9b655a6e 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -70,7 +70,7 @@ app.once('ready', function() { var BrowserWindow, chromeExtensionHandler, i, init, len, protocol, srcDirectory; protocol = electron.protocol, BrowserWindow = electron.BrowserWindow; - // Load persistented extensions. + // Load persisted extensions. loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions'); try { loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath)); From 5714ae0b73c722d2a57bbac182d671384b705314 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:08:46 -0800 Subject: [PATCH 002/132] Add failing spec for dev tools extensions file --- spec/api-browser-window-spec.js | 17 +++++++++++++++++ .../devtools-extensions/foo/manifest.json | 3 +++ 2 files changed, 20 insertions(+) create mode 100644 spec/fixtures/devtools-extensions/foo/manifest.json diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index fc8d3523c8fb..328325a376a1 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -8,6 +8,7 @@ const os = require('os'); const remote = require('electron').remote; const screen = require('electron').screen; +const app = remote.require('electron').app; const ipcMain = remote.require('electron').ipcMain; const BrowserWindow = remote.require('electron').BrowserWindow; @@ -618,4 +619,20 @@ describe('browser-window module', function() { }); }); }); + + describe('dev tool extensions', function () { + it('serializes the registered extensions on quit', function () { + var extensionName = 'foo' + var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName); + var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions'); + + BrowserWindow.addDevToolsExtension(extensionPath); + app.emit('will-quit'); + assert.deepEqual(JSON.parse(fs.readFileSync(serializedPath)), [extensionPath]); + + BrowserWindow.removeDevToolsExtension(extensionName); + app.emit('will-quit'); + assert.equal(fs.existsSync(serializedPath), false); + }) + }) }); diff --git a/spec/fixtures/devtools-extensions/foo/manifest.json b/spec/fixtures/devtools-extensions/foo/manifest.json new file mode 100644 index 000000000000..bde99de9287a --- /dev/null +++ b/spec/fixtures/devtools-extensions/foo/manifest.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} From 6252511b7fa5505ba4f47dfad9ff16f26fe0c5e0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:12:09 -0800 Subject: [PATCH 003/132] Delete extensions file when there are no loaded extensions --- atom/browser/lib/chrome-extension.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index eaed9b655a6e..e396989bcf38 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -54,12 +54,16 @@ app.on('will-quit', function() { loadedExtensions = Object.keys(extensionInfoMap).map(function(key) { return extensionInfoMap[key].srcDirectory; }); - try { - fs.mkdirSync(path.dirname(loadedExtensionsPath)); - } catch (error) { - // Ignore error + if (loadedExtensions.length > 0) { + try { + fs.mkdirSync(path.dirname(loadedExtensionsPath)); + } catch (error) { + // Ignore error + } + return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); + } else { + fs.unlinkSync(loadedExtensionsPath); } - return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); } catch (error) { // Ignore error } From adfa4844d1b1849b1b6ea7f2839fc037a5aba020 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:15:28 -0800 Subject: [PATCH 004/132] Don't return anything from will-quit handler --- atom/browser/lib/chrome-extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index e396989bcf38..fcbb8c7f15fd 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -60,7 +60,7 @@ app.on('will-quit', function() { } catch (error) { // Ignore error } - return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); + fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); } else { fs.unlinkSync(loadedExtensionsPath); } From 00261a5571d71d77850cd268e8ae8890716924bd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:17:11 -0800 Subject: [PATCH 005/132] Remove lint warnings --- spec/api-browser-window-spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 328325a376a1..a7d58d7feb87 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -622,7 +622,7 @@ describe('browser-window module', function() { describe('dev tool extensions', function () { it('serializes the registered extensions on quit', function () { - var extensionName = 'foo' + var extensionName = 'foo'; var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName); var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions'); @@ -633,6 +633,6 @@ describe('browser-window module', function() { BrowserWindow.removeDevToolsExtension(extensionName); app.emit('will-quit'); assert.equal(fs.existsSync(serializedPath), false); - }) - }) + }); + }); }); From e9aa24e340a3dd9b6ab3794c7bee1da1d359b37d Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 18:10:26 +0800 Subject: [PATCH 006/132] fix broken link --- docs-translations/zh-CN/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index 5e9c752d1d45..c4d668417e4c 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -127,7 +127,7 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ 在你完成了你的应用后,你可以按照[应用部署][4]指导发布一个版本,并且以已经打包好的形式运行应用。 - [1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-renderer.md + [1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-main-process.md [2]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/remote.md [3]: https://github.com/atom/electron/releases [4]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md From 6c8d9a5ccf2cd2970ea0aa7e627b374e38f57e45 Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 21:11:59 +0800 Subject: [PATCH 007/132] translate --- docs-translations/zh-CN/api/remote.md | 150 ++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 docs-translations/zh-CN/api/remote.md diff --git a/docs-translations/zh-CN/api/remote.md b/docs-translations/zh-CN/api/remote.md new file mode 100644 index 000000000000..049ce5fb32c7 --- /dev/null +++ b/docs-translations/zh-CN/api/remote.md @@ -0,0 +1,150 @@ +# remote + +`remote` 模块提供了一种在渲染进程(网页)和主进程之间进行进程间通讯(IPC)的简便途径。 + +Electron中, 与GUI相关的模块(如 `dialog`, `menu` 等)只存在于主进程,而不在渲染进程中 +。为了能从渲染进程中使用它们,需要用`ipc`模块来给主进程发送进程间消息。使用 `remote` +模块,可以调用主进程对象的方法,而无需显式地发送进程间消息,这类似于 Java 的 [RMI][rmi]。 +下面是从渲染进程创建一个浏览器窗口的例子: + +```javascript +const remote = require('electron').remote; +const BrowserWindow = remote.BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600 }); +win.loadURL('https://github.com'); +``` + +**注意:** 反向操作(从主进程访问渲染进程),可以使用[webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture). + +## 远程对象 + +`remote`模块返回的每个对象(包括函数)都代表了主进程中的一个对象(我们称之为远程对象或者远程函数)。 +当调用远程对象的方法、执行远程函数或者使用远程构造器(函数)创建新对象时,其实就是在发送同步的进程间消息。 + +在上面的例子中, `BrowserWindow` 和 `win` 都是远程对象,然而 +`new BrowserWindow` 并没有在渲染进程中创建 `BrowserWindow` 对象。 +而是在主进程中创建了 `BrowserWindow` 对象,并在渲染进程中返回了对应的远程对象,即 +`win` 对象。 + +请注意只有 [可枚举属性](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) 才能通过 remote 进行访问. + +## 远程对象的生命周期 + +Electron 确保在渲染进程中的远程对象存在(换句话说,没有被垃圾收集),那主进程中的对应对象也不会被释放。 +当远程对象被垃圾收集之后,主进程中的对应对象才会被取消关联。 + +如果远程对象在渲染进程泄露了(即,存在某个表中但永远不会释放),那么主进程中的对应对象也一样会泄露, +所以你必须小心不要泄露了远程对象。If the remote object is leaked in the renderer process (e.g. stored in a map but +never freed), the corresponding object in the main process will also be leaked, +so you should be very careful not to leak remote objects. + +不过,主要的值类型如字符串和数字,是传递的副本。 + +## 给主进程传递回调函数 + +在主进程中的代码可以从渲染进程——`remote`模块——中接受回调函数,但是使用这个功能的时候必须非常非常小心。Code in the main process can accept callbacks from the renderer - for instance +the `remote` module - but you should be extremely careful when using this +feature. + +首先,为了避免死锁,传递给主进程的回调函数会进行异步调用。所以不能期望主进程来获得传递过去的回调函数的返回值。First, in order to avoid deadlocks, the callbacks passed to the main process +are called asynchronously. You should not expect the main process to +get the return value of the passed callbacks. + +比如,在渲染进程For instance you can't use a function from the renderer process in an +`Array.map` called in the main process: + +```javascript +// 主进程 mapNumbers.js +exports.withRendererCallback = function(mapper) { + return [1,2,3].map(mapper); +} + +exports.withLocalCallback = function() { + return exports.mapNumbers(function(x) { + return x + 1; + }); +} +``` + +```javascript +// 渲染进程 +var mapNumbers = require("remote").require("./mapNumbers"); + +var withRendererCb = mapNumbers.withRendererCallback(function(x) { + return x + 1; +}) + +var withLocalCb = mapNumbers.withLocalCallback() + +console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] +``` + +As you can see, the renderer callback's synchronous return value was not as +expected, and didn't match the return value of an identical callback that lives +in the main process. + +Second, the callbacks passed to the main process will persist until the +main process garbage-collects them. + +For example, the following code seems innocent at first glance. It installs a +callback for the `close` event on a remote object: + +```javascript +remote.getCurrentWindow().on('close', function() { + // blabla... +}); +``` + +But remember the callback is referenced by the main process until you +explicitly uninstall it. If you do not, each time you reload your window the +callback will be installed again, leaking one callback for each restart. + +To make things worse, since the context of previously installed callbacks has +been released, exceptions will be raised in the main process when the `close` +event is emitted. + +To avoid this problem, ensure you clean up any references to renderer callbacks +passed to the main process. This involves cleaning up event handlers, or +ensuring the main process is explicitly told to deference callbacks that came +from a renderer process that is exiting. + +## Accessing built-in modules in the main process + +The built-in modules in the main process are added as getters in the `remote` +module, so you can use them directly like the `electron` module. + +```javascript +const app = remote.app; +``` + +## 方法 + +`remote` 模块有以下方法: + +### `remote.require(module)` + +* `module` String + +返回在主进程中执行 `require(module)` 所返回的对象。 + +### `remote.getCurrentWindow()` + +返回该网页所属的 [`BrowserWindow`](browser-window.md) 对象。 + +### `remote.getCurrentWebContents()` + +返回该网页的 [`WebContents`](web-contents.md) 对象 + +### `remote.getGlobal(name)` + +* `name` String + +返回在主进程中名为 `name` 的全局变量(即 `global[name]`) 。 + +### `remote.process` + +返回主进程中的 `process` 对象。等同于 +`remote.getGlobal('process')` 但是有缓存。 + +[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation From 55950281e8b0eccafe72372a8e668382c1bb21a4 Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 22:55:30 +0800 Subject: [PATCH 008/132] translate --- docs-translations/zh-CN/api/remote.md | 31 ++++++++------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/docs-translations/zh-CN/api/remote.md b/docs-translations/zh-CN/api/remote.md index 049ce5fb32c7..a686abf2f618 100644 --- a/docs-translations/zh-CN/api/remote.md +++ b/docs-translations/zh-CN/api/remote.md @@ -51,8 +51,7 @@ feature. are called asynchronously. You should not expect the main process to get the return value of the passed callbacks. -比如,在渲染进程For instance you can't use a function from the renderer process in an -`Array.map` called in the main process: +比如,你不能主进程中给`Array.map`传递来自渲染进程的函数。 ```javascript // 主进程 mapNumbers.js @@ -80,15 +79,11 @@ var withLocalCb = mapNumbers.withLocalCallback() console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] ``` -As you can see, the renderer callback's synchronous return value was not as -expected, and didn't match the return value of an identical callback that lives -in the main process. +如你所见,渲染器回调函数的同步返回值没有按预期产生,与主进程中的一模一样的回调函数的返回值不同。 -Second, the callbacks passed to the main process will persist until the -main process garbage-collects them. +其次,传递给主进程的函数会持续到主进程对他们进行垃圾回收。 -For example, the following code seems innocent at first glance. It installs a -callback for the `close` event on a remote object: +例如,下面的代码第一眼看上去毫无问题。给远程对象的`close`事件绑定了一个回调函数: ```javascript remote.getCurrentWindow().on('close', function() { @@ -96,23 +91,15 @@ remote.getCurrentWindow().on('close', function() { }); ``` -But remember the callback is referenced by the main process until you -explicitly uninstall it. If you do not, each time you reload your window the -callback will be installed again, leaking one callback for each restart. +但记住主进程会一直保持对这个回调函数的引用,除非明确的卸载它。如果不卸载,每次重新载入窗口都会再次绑定,这样每次重启就会泄露一个回调函数。 -To make things worse, since the context of previously installed callbacks has -been released, exceptions will be raised in the main process when the `close` -event is emitted. +更严重的是,由于前面安装了回调函数的上下文已经被释放,所以当主进程的 `close` 事件触发的时候,会抛出异常。 -To avoid this problem, ensure you clean up any references to renderer callbacks -passed to the main process. This involves cleaning up event handlers, or -ensuring the main process is explicitly told to deference callbacks that came -from a renderer process that is exiting. +为了避免这个问题,要确保对传递给主进程的渲染器的回调函数进行清理。可以清理事件处理器,或者明确告诉主进行取消来自已经退出的渲染器进程中的回调函数。 -## Accessing built-in modules in the main process +## 访问主进程中的内置模块 -The built-in modules in the main process are added as getters in the `remote` -module, so you can use them directly like the `electron` module. +在主进程中的内置模块已经被添加为`remote`模块中的属性,所以可以直接像使用`electron`模块一样直接使用它们。 ```javascript const app = remote.app; From 8df3856c8f26ed3f1e9ece48850a26fc4466eced Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 09:16:40 -0800 Subject: [PATCH 009/132] Use const for fs/path requires --- atom/browser/default_app/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 895e3df63660..c24fc12ac3cb 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -4,8 +4,8 @@ const dialog = electron.dialog; const shell = electron.shell; const Menu = electron.Menu; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function() { From 2e96cab6aa82fd9e77778699a761f19112181463 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:07:19 -0800 Subject: [PATCH 010/132] Extract helper function to load specified app --- atom/browser/default_app/main.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index c24fc12ac3cb..c562824daffa 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -234,12 +234,10 @@ if (option.modules.length > 0) { require('module')._preloadModules(option.modules); } -// Start the specified app if there is one specified in command line, otherwise -// start the default app. -if (option.file && !option.webdriver) { +function loadPackagePath(packagePath) { try { // Override app name and version. - var packagePath = path.resolve(option.file); + packagePath = path.resolve(packagePath); var packageJsonPath = path.join(packagePath, 'package.json'); if (fs.existsSync(packageJsonPath)) { var packageJson = JSON.parse(fs.readFileSync(packageJsonPath)); @@ -270,6 +268,12 @@ if (option.file && !option.webdriver) { throw e; } } +} + +// Start the specified app if there is one specified in command line, otherwise +// start the default app. +if (option.file && !option.webdriver) { + loadPackagePath(option.file); } else if (option.version) { console.log('v' + process.versions.electron); process.exit(0); From 69687c92e96cf59a5a66ff029cfd18d6ad62ad00 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:26:11 -0800 Subject: [PATCH 011/132] Add support for launching http URL directly --- atom/browser/default_app/default_app.js | 20 +++++++++++--------- atom/browser/default_app/main.js | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 2ec765d0d691..ebcca2a5d9a5 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -9,13 +9,15 @@ app.on('window-all-closed', function() { app.quit(); }); -app.on('ready', function() { - mainWindow = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - useContentSize: true, +exports.load = function(appUrl) { + app.on('ready', function() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + useContentSize: true, + }); + mainWindow.loadURL(appUrl); + mainWindow.focus(); }); - mainWindow.loadURL('file://' + __dirname + '/index.html'); - mainWindow.focus(); -}); +}; diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index c562824daffa..2b5c916749d3 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -6,6 +6,7 @@ const Menu = electron.Menu; const fs = require('fs'); const path = require('path'); +const url = require('url'); // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function() { @@ -270,10 +271,19 @@ function loadPackagePath(packagePath) { } } +function loadApplicationByUrl(appUrl) { + require('./default_app').load(appUrl); +} + // Start the specified app if there is one specified in command line, otherwise // start the default app. if (option.file && !option.webdriver) { - loadPackagePath(option.file); + var protocol = url.parse(option.file).protocol; + if (protocol === 'http:' || protocol === 'https:') { + loadApplicationByUrl(option.file); + } else { + loadPackagePath(option.file); + } } else if (option.version) { console.log('v' + process.versions.electron); process.exit(0); @@ -289,5 +299,5 @@ if (option.file && !option.webdriver) { console.log(helpMessage); process.exit(0); } else { - require('./default_app'); + loadApplicationByUrl('file://' + __dirname + '/index.html'); } From 312182e0bdd8d71cf7a26ffaa54daf825ad7fbb8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:33:22 -0800 Subject: [PATCH 012/132] Add support for launching HTML files directly --- atom/browser/default_app/main.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 2b5c916749d3..09082804b3cd 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -278,11 +278,15 @@ function loadApplicationByUrl(appUrl) { // Start the specified app if there is one specified in command line, otherwise // start the default app. if (option.file && !option.webdriver) { - var protocol = url.parse(option.file).protocol; + var file = option.file; + var protocol = url.parse(file).protocol; + var extension = path.extname(file); if (protocol === 'http:' || protocol === 'https:') { - loadApplicationByUrl(option.file); + loadApplicationByUrl(file); + } else if (extension === '.html' || extension === '.htm') { + loadApplicationByUrl('file://' + path.resolve(file)); } else { - loadPackagePath(option.file); + loadPackagePath(file); } } else if (option.version) { console.log('v' + process.versions.electron); From b74dd43ff564430a54b261688f9cd78dfb46b0b4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:34:36 -0800 Subject: [PATCH 013/132] Support opening file: URLs directly --- atom/browser/default_app/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 09082804b3cd..3ec80a6975f4 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -281,7 +281,7 @@ if (option.file && !option.webdriver) { var file = option.file; var protocol = url.parse(file).protocol; var extension = path.extname(file); - if (protocol === 'http:' || protocol === 'https:') { + if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:') { loadApplicationByUrl(file); } else if (extension === '.html' || extension === '.htm') { loadApplicationByUrl('file://' + path.resolve(file)); From f482ea4902738e3135a732b24daa50ef2a494383 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:35:17 -0800 Subject: [PATCH 014/132] loadPackagePath -> loadApplicationPackage --- atom/browser/default_app/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 3ec80a6975f4..855d2463d25b 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -235,7 +235,7 @@ if (option.modules.length > 0) { require('module')._preloadModules(option.modules); } -function loadPackagePath(packagePath) { +function loadApplicationPackage(packagePath) { try { // Override app name and version. packagePath = path.resolve(packagePath); @@ -286,7 +286,7 @@ if (option.file && !option.webdriver) { } else if (extension === '.html' || extension === '.htm') { loadApplicationByUrl('file://' + path.resolve(file)); } else { - loadPackagePath(file); + loadApplicationPackage(file); } } else if (option.version) { console.log('v' + process.versions.electron); From fa4ad9d95f6ad7243783a6e7de24ce0b0f9e819d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:45:52 -0800 Subject: [PATCH 015/132] Tweak help message for new path options --- atom/browser/default_app/main.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 855d2463d25b..6ff26e9ea679 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -294,9 +294,14 @@ if (option.file && !option.webdriver) { } else if (option.help) { var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n"; helpMessage += "Usage: electron [options] [path]\n\n"; - helpMessage += "A path to an Electron application may be specified. The path must be to \n"; - helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n"; - helpMessage += "Options:\n"; + helpMessage += "A path to an Electron application may be specified.\n"; + helpMessage += "The path must be one of the following:\n\n"; + helpMessage += " - index.js file.\n"; + helpMessage += " - Folder containing a package.json file.\n"; + helpMessage += " - Folder containing an index.js file.\n"; + helpMessage += " - .html/.htm file.\n"; + helpMessage += " - http://, https://, or file:// URL.\n"; + helpMessage += "\nOptions:\n"; helpMessage += " -r, --require Module to preload (option can be repeated)\n"; helpMessage += " -h, --help Print this usage message.\n"; helpMessage += " -v, --version Print the version."; From fa734d7824ae9bf1bae7fe0fad2e35fde40b1406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Aur=C3=A8le=20DARCHE?= Date: Sat, 6 Feb 2016 19:57:21 +0100 Subject: [PATCH 016/132] Document different techniques to share objects This has been discussed in --- docs/faq/electron-faq.md | 34 ++++++++++++++++++++++++++++++++++ docs/tutorial/quick-start.md | 3 +++ 2 files changed, 37 insertions(+) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 643bde7409b2..d5470f701734 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -18,6 +18,40 @@ New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron. +## What are the different techniques to share objects between web pages? + +To share objects between web pages (that is on the renderer side) the simplest +and more natural technique is to use a web standard API already available in all +browsers. A good candidate is the +[Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage), +through either the +[`window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) property or the +[`window.sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) property. +Note that the Storage API allows only to store strings, so objects must be +serialized as JSON. +Another candidate is +[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). + +Another technique, but this time specific to Electron, is to store objects in +the main process as a global variable and then to access them from the renderers +through the `remote` module: + +```javascript +// In main.js of browser process +global.sharedObject = {}; +``` + +```javascript +// js in page-1.html +require('remote').getGlobal('sharedObject').someProperty = 'some value'; +``` + +```javascript +// js in page-2.html +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + + ## My app's window/tray disappeared after a few minutes. This happens when the variable which is used to store the window/tray gets diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ebf907e070f2..ccb3836ba1f7 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -47,6 +47,9 @@ In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for communication between the main process and renderer process. There is also a [remote](../api/remote.md) module for RPC style communication. +And finally there are different techniques [to share objects between web +pages](../faq/electron-faq.md#) of the same window or of different windows. + ## Write your First Electron App Generally, an Electron app is structured like this: From 702455674bbf721f2191bf294b54a2107eb2dfd2 Mon Sep 17 00:00:00 2001 From: Michael Vasseur Date: Sun, 7 Feb 2016 10:20:38 +0100 Subject: [PATCH 017/132] Using node::Buffer::Copy() instead of node::Buffer::New() to copy the handle bytes to buffer make the buffer really contains the data. --- atom/browser/api/atom_api_window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bcf6ccc5a335..ea1d95b79ca0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -109,7 +109,7 @@ void TranslateOldOptions(v8::Isolate* isolate, v8::Local options) { // Converts binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { - auto buffer = node::Buffer::New(isolate, static_cast(val), size); + auto buffer = node::Buffer::Copy(isolate, static_cast(val), size); if (buffer.IsEmpty()) return v8::Null(isolate); else From 756aeffe03fabb7939a1fd156217f67dabeebc88 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 8 Feb 2016 15:18:05 -0800 Subject: [PATCH 018/132] Set icon on NSAlert when specified --- atom/browser/ui/message_box_mac.mm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index f9e9718ebf55..9380f01e384d 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -8,7 +8,9 @@ #include "atom/browser/native_window.h" #include "base/callback.h" +#include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" +#include "skia/ext/skia_utils_mac.h" @interface ModalDelegate : NSObject { @private @@ -57,7 +59,8 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, int default_id, const std::string& title, const std::string& message, - const std::string& detail) { + const std::string& detail, + const gfx::ImageSkia& icon) { // Ignore the title; it's the window title on other platforms and ignorable. NSAlert* alert = [[NSAlert alloc] init]; [alert setMessageText:base::SysUTF8ToNSString(message)]; @@ -92,6 +95,12 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, [[ns_buttons objectAtIndex:default_id] setKeyEquivalent:@"\r"]; } + if (!icon.isNull()) { + NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( + *icon.bitmap(), base::mac::GetGenericRGBColorSpace()); + [alert setIcon:image]; + } + return alert; } @@ -113,7 +122,7 @@ int ShowMessageBox(NativeWindow* parent_window, const gfx::ImageSkia& icon) { NSAlert* alert = CreateNSAlert( parent_window, type, buttons, default_id, title, message, - detail); + detail, icon); // Use runModal for synchronous alert without parent, since we don't have a // window to wait for. @@ -149,7 +158,7 @@ void ShowMessageBox(NativeWindow* parent_window, const MessageBoxCallback& callback) { NSAlert* alert = CreateNSAlert( parent_window, type, buttons, default_id, title, message, - detail); + detail, icon); ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback andAlert:alert callEndModal:false]; From 5a8bebc2f8faf6a84073e7dd27fd519a14e5ce67 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 11 Feb 2016 08:24:50 +0530 Subject: [PATCH 019/132] browser: emit did-fail-load for invalid url --- atom/browser/api/atom_api_web_contents.cc | 8 ++++++++ spec/api-browser-window-spec.js | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 80e5b606ef8d..a7946786c514 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -710,6 +710,14 @@ bool WebContents::Equal(const WebContents* web_contents) const { } void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { + if (!url.is_valid()) { + Emit("did-fail-load", + static_cast(net::ERR_INVALID_URL), + net::ErrorToShortString(net::ERR_INVALID_URL), + url.possibly_invalid_spec()); + return; + } + content::NavigationController::LoadURLParams params(url); GURL http_referrer; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index fc8d3523c8fb..72d28bcb6ed0 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -94,11 +94,20 @@ describe('browser-window module', function() { }); return w.loadURL('about:blank'); }); - return it('should emit did-fail-load event', function(done) { - w.webContents.on('did-fail-load', function() { - return done(); + it('should emit did-fail-load event for files that do not exist', function(done) { + w.webContents.on('did-fail-load', function(event, code) { + assert.equal(code, -6); + done(); }); - return w.loadURL('file://a.txt'); + w.loadURL('file://a.txt'); + }); + it('should emit did-fail-load event for invalid URL', function(done) { + w.webContents.on('did-fail-load', function(event, code, desc) { + assert.equal(desc, 'ERR_INVALID_URL'); + assert.equal(code, -300); + done(); + }); + w.loadURL('http://example:port'); }); }); describe('BrowserWindow.show()', function() { From 6d2ad5ae5881c2d4af9b41a69eef3e5e83814b60 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Thu, 11 Feb 2016 15:34:19 -0500 Subject: [PATCH 020/132] Add ability to specify command line switches in package.json --- atom/browser/lib/init.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index 272cebbf875b..df0f1b6685ae 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -132,6 +132,19 @@ if (packageJson.desktopName != null) { // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); +// Add othercommand line switches +if (packageJson.commandLineSwitches) { + for (let i = 0; i < packageJson.commandLineSwitches.length; ++i) { + const option = packageJson.commandLineSwitches[i]; + + if (typeof option === 'string') { + app.commandLine.appendSwitch(option); + } else { + app.commandLine.appendSwitch(option[0], option[1]); + } + } +} + // Set the user path according to application's name. app.setPath('userData', path.join(app.getPath('appData'), app.getName())); From dbb4e21684a37ce20553c4b04672937d2e6ff887 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Thu, 11 Feb 2016 15:41:36 -0500 Subject: [PATCH 021/132] Fix index increment --- atom/browser/lib/init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index df0f1b6685ae..b687aa6eedad 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -132,9 +132,9 @@ if (packageJson.desktopName != null) { // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); -// Add othercommand line switches +// Add other command line switches if (packageJson.commandLineSwitches) { - for (let i = 0; i < packageJson.commandLineSwitches.length; ++i) { + for (let i = 0; i < packageJson.commandLineSwitches.length; i++) { const option = packageJson.commandLineSwitches[i]; if (typeof option === 'string') { From c09ff40916bec47b6c7a09ea8c0c8a1d0e591642 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 12 Feb 2016 05:07:06 +0530 Subject: [PATCH 022/132] browser: handle desktop capture devices in media permission request --- atom/browser/web_contents_permission_helper.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index f5ce414dd2ca..d018e1d09dbc 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -23,7 +23,7 @@ void MediaAccessAllowed( bool allowed) { brightray::MediaStreamDevicesController controller(request, callback); if (allowed) - controller.Accept(); + controller.TakeAction(); else controller.Deny(content::MEDIA_DEVICE_PERMISSION_DENIED); } From 3adcaa7681fdff87186aa08689c2b3567aaa78cb Mon Sep 17 00:00:00 2001 From: Habib Rehman Date: Fri, 12 Feb 2016 00:11:02 +0000 Subject: [PATCH 023/132] Fix electron binary relative path The relative path for Electron's binary is Contents/MacOS/Electron --- docs/tutorial/using-selenium-and-webdriver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/using-selenium-and-webdriver.md b/docs/tutorial/using-selenium-and-webdriver.md index 035dabdfe79f..2d296548dd9c 100644 --- a/docs/tutorial/using-selenium-and-webdriver.md +++ b/docs/tutorial/using-selenium-and-webdriver.md @@ -49,7 +49,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // Here is the path to your Electron binary. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') From 91c96559fa40e50e7c364bb7f0dafc594692390f Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Fri, 12 Feb 2016 02:18:13 +0100 Subject: [PATCH 024/132] Fixing the problem related to FrameSubscriber --- atom/browser/api/atom_api_web_contents.cc | 8 +++-- atom/browser/api/frame_subscriber.cc | 40 ++++++++++++++++++++--- atom/browser/api/frame_subscriber.h | 27 ++++++++++++--- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 80e5b606ef8d..b04553e654b8 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1064,9 +1064,11 @@ void WebContents::BeginFrameSubscription( const FrameSubscriber::FrameCaptureCallback& callback) { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { - scoped_ptr frame_subscriber(new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback)); - view->BeginFrameSubscription(frame_subscriber.Pass()); + FrameSubscriber* frame_subscriber = new FrameSubscriber( + isolate(), view->GetVisibleViewportSize(), callback); + scoped_ptr del_frame_subscriber( + frame_subscriber->GetSubscriber()); + view->BeginFrameSubscription(del_frame_subscriber.Pass()); } } diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 5b7241486b72..9bcf16fef857 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -13,28 +13,58 @@ namespace atom { namespace api { +using Subscriber = FrameSubscriber::Subscriber; + FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback) { + : isolate_(isolate), size_(size), callback_(callback), pending_frames(0) { + subscriber_ = new Subscriber(this); } -bool FrameSubscriber::ShouldCaptureFrame( +Subscriber::Subscriber( + FrameSubscriber* frame_subscriber) : frame_subscriber_(frame_subscriber) { +} + +Subscriber::~Subscriber() { + frame_subscriber_->subscriber_ = NULL; + frame_subscriber_->RequestDestruct(); +} + +bool Subscriber::ShouldCaptureFrame( const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { *storage = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_YV12, - size_, gfx::Rect(size_), size_, base::TimeDelta()); + frame_subscriber_->size_, gfx::Rect(frame_subscriber_->size_), + frame_subscriber_->size_, base::TimeDelta()); *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - base::Unretained(this), *storage); + base::Unretained(frame_subscriber_), *storage); + frame_subscriber_->pending_frames++; return true; } +Subscriber* FrameSubscriber::GetSubscriber() { + return subscriber_; +} + +bool FrameSubscriber::RequestDestruct() { + bool deletable = (subscriber_ == NULL && pending_frames == 0); + // Destruct FrameSubscriber if we're not waiting for frames and the + // subscription has ended + if (deletable) + delete this; + + return deletable; +} + void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { - if (!result) + pending_frames--; + + if (!result || RequestDestruct()) return; v8::Locker locker(isolate_); diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index f7748aa5790d..6f6d66b6be80 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -14,26 +14,43 @@ namespace atom { namespace api { -class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { +class FrameSubscriber { public: using FrameCaptureCallback = base::Callback)>; + // Inner class that is the actual subscriber sent to chromium + class Subscriber : + public content::RenderWidgetHostViewFrameSubscriber { + public: + explicit Subscriber(FrameSubscriber* frame_subscriber); + + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; + + ~Subscriber(); + private: + FrameSubscriber* frame_subscriber_; + }; + FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback); - bool ShouldCaptureFrame(const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) override; + Subscriber* GetSubscriber(); private: void OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool); + bool RequestDestruct(); + v8::Isolate* isolate_; gfx::Size size_; FrameCaptureCallback callback_; + Subscriber* subscriber_; + int pending_frames; DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); }; From f36e2841bff038de2f7cf7649544a589979a06a3 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Fri, 12 Feb 2016 13:30:11 +0100 Subject: [PATCH 025/132] Don't fire callbacks after we end the subscription --- atom/browser/api/frame_subscriber.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 9bcf16fef857..7d973892405c 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -64,7 +64,7 @@ void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { pending_frames--; - if (!result || RequestDestruct()) + if (RequestDestruct() || subscriber_ == NULL || !result) return; v8::Locker locker(isolate_); From 2677dc68444398f20210291dfaf7349fc17dc48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Aur=C3=A8le=20DARCHE?= Date: Fri, 12 Feb 2016 13:50:15 +0100 Subject: [PATCH 026/132] Fix: add missing fragment in FAQ section URL --- docs/tutorial/quick-start.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ccb3836ba1f7..67fe5d608a13 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -48,7 +48,8 @@ communication between the main process and renderer process. There is also a [remote](../api/remote.md) module for RPC style communication. And finally there are different techniques [to share objects between web -pages](../faq/electron-faq.md#) of the same window or of different windows. +pages](../faq/electron-faq.md#what-are-the-different-techniques-to-share-objects-between-web-pages) +of the same window or of different windows. ## Write your First Electron App From e71eeda73c5f8d8a760ce63d6976d394257a5e27 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 12 Feb 2016 22:38:08 +0900 Subject: [PATCH 027/132] Remove unnecessary line feeds [ci skip] --- docs/api/clipboard.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index dcb9fa398a90..7f95a1af26d2 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -67,7 +67,6 @@ Writes `image` to the clipboard. Returns the content in the clipboard as RTF. - ### `clipboard.writeRtf(text[, type])` * `text` String From d76f6fe8e0d6faee5c542e79f86202a6f89245b5 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sat, 13 Feb 2016 17:03:58 +0900 Subject: [PATCH 028/132] :memo::checkered_flag: Add icon overlays in taskbar to docs [ci skip] --- .../desktop-environment-integration.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 7d7eb44ecb6e..54246a11c5c1 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -271,6 +271,33 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## Icon Overlays in Taskbar (Windows) + +On Windows a taskbar button can use a small overlay to display application +status, as quoted from MSDN: + +> Icon overlays serve as a contextual notification of status, and are intended +> to negate the need for a separate notification area status icon to communicate +> that information to the user. For instance, the new mail status in Microsoft +> Outlook, currently shown in the notification area, can now be indicated +> through an overlay on the taskbar button. Again, you must decide during your +> development cycle which method is best for your application. Overlay icons are +> intended to supply important, long-standing status or notifications such as +> network status, messenger status, or new mail. The user should not be +> presented with constantly changing overlays or animations. + +__Overlay on taskbar button:__ + +![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +To set the overlay icon for a window, you can use the +[BrowserWindow.setOverlayIcon][setoverlayicon] API: + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## Represented File of Window (OS X) On OS X a window can set its represented file, so the file's icon can show in @@ -298,6 +325,7 @@ window.setDocumentEdited(true); [clearrecentdocuments]: ../api/app.md#appclearrecentdocuments [setusertaskstasks]: ../api/app.md#appsetusertaskstasks [setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 [setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename [setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx From adf89a1e0eff739c9bfef7af614fbb403c982349 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 11:29:08 +0100 Subject: [PATCH 029/132] Translate README in french [ci skip] --- docs-translations/fr-FR/README.md | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 docs-translations/fr-FR/README.md diff --git a/docs-translations/fr-FR/README.md b/docs-translations/fr-FR/README.md new file mode 100644 index 000000000000..04aed4556124 --- /dev/null +++ b/docs-translations/fr-FR/README.md @@ -0,0 +1,91 @@ +Vérifiez que vous utilisez la bonne version de la documentation. +Le numéro de version devrait faire partie de l'URL de la page. +Si ce n'est pas le cas, vous utilisez probablement la documentation d'une branche +de développement qui peut contenir des changements API qui ne sont pas compatibles +avec votre version d'Electron. Si c'est le cas, vous pouvez changer de version sur la +liste [versions disponibles](http://electron.atom.io/docs/), ou, si vous utilisez +l'interface de GitHub, ouvrez la liste déroulante "Switch branches/tags" afin de sélectionner +le tag de votre version. + +## FAQ + +Avant de créer un ticket, vérifiez que votre problème n'a pas déjà sa réponse +dans la FAQ : + +* [Electron FAQ](faq/electron-faq.md) + +## Guides + +* [Plateformes supportées](tutorial/supported-platforms.md) +* [Distribution de l'Application](tutorial/application-distribution.md) +* [Guide de Soumission Mac App Store](tutorial/mac-app-store-submission-guide.md) +* [Créer une archive](tutorial/application-packaging.md) +* [Utiliser Modules Natifs de Node](tutorial/using-native-node-modules.md) +* [Debugger Processus Principal](tutorial/debugging-main-process.md) +* [Utiliser Selenium et WebDriver](tutorial/using-selenium-and-webdriver.md) +* [Extension DevTools](tutorial/devtools-extension.md) +* [Utiliser le Plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md) +* [Utiliser le Plugin Widevine CDM](tutorial/using-widevine-cdm-plugin.md) + +## Tutoriels + +* [Démarrage Rapide](tutorial/quick-start.md) +* [Intégration Environnement de Bureau](tutorial/desktop-environment-integration.md) +* [Détection des Evènements En ligne/Hors ligne](tutorial/online-offline-events.md) + +## Références API + +* [Synopsis](api/synopsis.md) +* [L'objet Process](api/process.md) +* [Commandes Chromes Supportées](api/chrome-command-line-switches.md) +* [Variables d'Environnement](api/environment-variables.md) + +### Eléments DOM Personnalisés: + +* [Objet `File`](api/file-object.md) +* [Tag ``](api/web-view-tag.md) +* [Fonction `window.open`](api/window-open.md) + +### Modules pour le Processus Principal : + +* [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) + +### Modules pour le Processus d'Affichage (Page Web) : + +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) +* [remote](api/remote.md) +* [webFrame](api/web-frame.md) + +### Modules pour les deux Processus : + +* [clipboard](api/clipboard.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Développement + +* [Style de Code](development/coding-style.md) +* [Hiérarchie du Code Source](development/source-code-directory-structure.md) +* [Différences Techniques par rapport à NW.js (anciennement node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Aperçu du Système de Build](development/build-system-overview.md) +* [Instructions de Build (OS X)](development/build-instructions-osx.md) +* [Instructions de Build (Windows)](development/build-instructions-windows.md) +* [Instructions de Build (Linux)](development/build-instructions-linux.md) +* [Installer un Serveur de Symbol dans le debugger](development/setting-up-symbol-server.md) From 940c325e7f89f90e8151b9ed56734a03bea5e1d1 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 11:32:47 +0100 Subject: [PATCH 030/132] Add french docs link on main README [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a7306ddabbb6..ce6d483f0dff 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ contains documents describing how to build and contribute to Electron. - [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) - [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA) - [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU) +- [French](https://github.com/atom/electron/tree/master/docs-translations/fr-FR) ## Quick Start From a69341f551e0078d843edab7e289f3c65b4db0d9 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 18:19:49 +0100 Subject: [PATCH 031/132] Fix line length wrap [ci skip] --- docs-translations/fr-FR/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs-translations/fr-FR/README.md b/docs-translations/fr-FR/README.md index 04aed4556124..666a03e99a3a 100644 --- a/docs-translations/fr-FR/README.md +++ b/docs-translations/fr-FR/README.md @@ -1,11 +1,11 @@ Vérifiez que vous utilisez la bonne version de la documentation. Le numéro de version devrait faire partie de l'URL de la page. -Si ce n'est pas le cas, vous utilisez probablement la documentation d'une branche -de développement qui peut contenir des changements API qui ne sont pas compatibles -avec votre version d'Electron. Si c'est le cas, vous pouvez changer de version sur la -liste [versions disponibles](http://electron.atom.io/docs/), ou, si vous utilisez -l'interface de GitHub, ouvrez la liste déroulante "Switch branches/tags" afin de sélectionner -le tag de votre version. +Si ce n'est pas le cas, vous utilisez probablement la documentation d'une +branche de développement qui peut contenir des changements API qui ne sont pas +compatibles avec votre version d'Electron. Si c'est le cas, vous pouvez changer +de version sur la liste [versions disponibles](http://electron.atom.io/docs/), +ou, si vous utilisez l'interface de GitHub, ouvrez la liste déroulante "Switch +branches/tags" afin de sélectionner le tag de votre version. ## FAQ From efd25efaf4ea00c2fac14f1d6ee4a76fab89c57f Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 18:20:34 +0100 Subject: [PATCH 032/132] Add FAQ [ci skip] --- docs-translations/fr-FR/faq/electron-faq.md | 129 ++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs-translations/fr-FR/faq/electron-faq.md diff --git a/docs-translations/fr-FR/faq/electron-faq.md b/docs-translations/fr-FR/faq/electron-faq.md new file mode 100644 index 000000000000..1a82bce68009 --- /dev/null +++ b/docs-translations/fr-FR/faq/electron-faq.md @@ -0,0 +1,129 @@ +# Electron FAQ + +## Quand est mise à jour la version de Chrome utilisée par Electron ? + +La version de Chrome qu'utilise Electron est en général mise à jour une ou deux +semaines après la sortie d'une nouvelle version stable de Chrome. + +Etant donné que nous n'utilisons que les versions stables de Chrome, si un fix +important est en beta ou en dev, nous l'intégrerons à la version que nous +utilisons. + +## Quand est mise à jour la version de Node.js utilisée par Electron ? + +Quand une nouvelle version de Node.js sort, nous attendons en général un mois +avant de mettre à jour celle que nous utilisons dans Electron. Ceci afin +d'éviter les bugs introduits par les nouvelles versions, ce qui arrive très +souvent. + +Les nouvelles fonctionnalités de Node.js arrivant la plupart du temps via V8, +et Electron utilisant le V8 du navigateur Chrome, la nouvelle fonctionnalité +JavaScript de la nouvelle version de Node.js est bien souvent déjà dans +Electron. + +## La fenêtre/barre d'état de mon application disparait après quelques minutes. + +Cela se produit quand la variable qui est utilisée pour stocker la fenêtre/barre +d'état est libérée par le ramasse-miettes. + +Nous vous recommandons de lire les articles suivants quand vous rencontrez le +problème : + +* [Management de la Mémoire][memory-management] (Anglais) +* [Portée d'une Variable][variable-scope] (Anglais) + +Si vous voulez corriger rapidement le problème, vous pouvez rendre les variables +globales en changeant votre code de ça : + +```javascript +app.on('ready', function() { + var tray = new Tray('/path/to/icon.png'); +}) +``` + +à ça : + +```javascript +var tray = null; +app.on('ready', function() { + tray = new Tray('/path/to/icon.png'); +}) +``` + +## Je n'arrive pas à utiliser jQuery/RequireJS/Meteor/AngularJS dans Electron. + +A cause de l'intégration de Node.js dans Electron, certains mots-clés sont +insérés dans la DOM, comme `module`, `exports`, `require`. Ceci pose des +problèmes pour certaines bibliothèques qui utilisent les mêmes mots-clés. + +Pour résoudre ce problème, vous pouvez désactiver l'intégration de node dans +Electron : + +```javascript +// Dans le processus principal. +var mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: false + } +}); +``` + +Mais si vous voulez garder la possibilité d'utiliser Node.js et les APIs +Electron, vous devez renommer les mots-clés dans la page avant d'inclure +d'autres bibliothèques : + +```html + + + + +``` + +## `require('electron').xxx` is undefined. + +Lors de l'utilisation des modules d'Electron, vous pouvez avoir une erreur : + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +Ceci se produit quand vous avez le [module npm `electron`][electron-module] +d'installé, soit en local ou en global, ce qui a pour effet d'écraser les +modules de base d'Electron. + +Vous vérifiez que vous utilisez les bons modules, vous pouvez afficher le +chemin du module `electron` : + +```javascript +console.log(require.resolve('electron')); +``` + +et vérifier si il est de la forme : + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +S'il est de la forme `node_modules/electron/index.js`, vous devez supprimer le +module npm `electron`, ou le renommer. + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +Si vous utilisez le module de base mais que vous continuez d'avoir +l'erreur, ça vient probablement du fait que vous utilisez le module dans le +mauvais processus. Par exemple `electron.app` peut uniquement être utilisé +dans le processus principal, tandis que `electron.webFrame` est uniquement +disponible dans le processus d'affichage. + +[memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management +[variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron From ef290ffcf2c1b3fdffb1eb004f0090026150bbe6 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 19:28:12 +0100 Subject: [PATCH 033/132] Add styleguide in french [ci skip] --- docs-translations/fr-FR/styleguide.md | 101 ++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 docs-translations/fr-FR/styleguide.md diff --git a/docs-translations/fr-FR/styleguide.md b/docs-translations/fr-FR/styleguide.md new file mode 100644 index 000000000000..5fe781773c12 --- /dev/null +++ b/docs-translations/fr-FR/styleguide.md @@ -0,0 +1,101 @@ +# Règles de style pour la documentation d'Electron + +Choisissez la section appropriée : [lire la documentation d'Electron](#reading-electron-documentation) +ou [écrire de la documentation pour Electron](#writing-electron-documentation). + +## Ecrire de la documentation pour Electron + +La documentation d'Electron a été écrite en suivant les règles ci-dessous : + +- Maximum un titre `h1` par page. +- Utilisation de `bash` au lieu de `cmd` dans les blocs de code (à cause de la + coloration syntaxique). +- Les titres `h1` devraient reprendre le nom de l'objet (i.e. `browser-window` → + `BrowserWindow`). + - Cependant, les traits d'union sont acceptés pour les noms de fichier. +- Pas de titre directement après un autre, ajoutez au minimum une ligne de + description entre les deux. +- Les entêtes des méthodes sont entre accents graves (backquotes) `code`. +- Les entêtes des évènements sont entre des apostrophes 'quotation'. +- Les listes ne doivent pas dépasser 2 niveaux (à cause du formattage du + markdown). +- Ajouter des titres de section: Evènements, Méthodes de classe, et Méthodes + d'instance. +- Utiliser 'will' au lieu de 'would' lors de la description du retour. +- Les évènements et méthodes sont des titres `h3`. +- Les arguments optionnels sont notés `function (required[, optional])`. +- Les arguments optionnels sont indiqués quand appelés dans la liste. +- La longueur des lignes ne dépasse pas 80 caractères. +- Les méthodes spécifiques à une plateforme sont notées en italique. + - ```### `method(foo, bar)` _OS X_``` +- Préférer 'in the ___ process' au lieu de 'on' + +### Traductions de la Documentation + +Les traductions de la documentation d'Electron sont dans le dossier +`docs-translations`. + +Pour ajouter une nouvelle langue (ou commencer) : + +- Créer un sous-dossier avec comme nom le code langage. +- A l'intérieur de ce dossier, dupliquer le dossier `docs`, en gardant le même + nom de dossiers et de fichiers. +- Traduire les fichiers. +- Mettre à jour le `README.md` à l'intérieur du dossier de langue en mettant les + liens vers les fichiers traduits. +- Ajouter un lien vers le nouveau dossier de langue dans le [README](https://github.com/atom/electron#documentation-translations) + principal d'Electron. + +## Lire la documentation d'Electron + +Quelques indications pour comprendre la syntaxe de la documentation d'Electron. + +### Méthodes + +Un exemple de la documentation d'une [méthode](https://developer.mozilla.org/en-US/docs/Glossary/Method) +(Anglais) + +--- + +`methodName(required[, optional]))` + +* `require` String (**required**) +* `optional` Integer + +--- + +Le nom de la méthode est suivi des arguments de celle-ci. Les arguments +optionnels sont notés entre crochets, avec une virgule si ceux-ci suivent un +autre argument. + +En-dessous de la méthode, chaque argument est détaillé avec son type. +Celui-ci peut être un type générique : +[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), +[`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), +[`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), +[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +ou un type personnalisé comme le [`webContent`](api/web-content.md) d'Electron. + +### Evènements + +Un exemple d'une documentation d'un [évènement](https://developer.mozilla.org/en-US/docs/Web/API/Event) +(Anglais) +--- + +Event: 'wake-up' + +Returns: + +* `time` String + +--- + +L'évènement est une chaine utilisée après un listener `.on`. Si il retourne une +valeur, elle est écrite en dessous ainsi que son type. Si vous voulez écouter et +répondre à l'évènement wake-up, ça donne quelque chose comme : + +```javascript +Alarm.on('wake-up', function(time) { + console.log(time) +}) +``` From f63d8b4d5ec2a139e616acd14330630fd254105d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 7 Feb 2016 16:02:48 +0900 Subject: [PATCH 034/132] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/api/browser-window.md | 2 +- docs-translations/ko-KR/api/clipboard.md | 13 +++++++++++++ docs-translations/ko-KR/api/ipc-renderer.md | 8 ++++---- docs-translations/ko-KR/api/session.md | 8 ++++---- .../ko-KR/tutorial/application-distribution.md | 5 ++--- .../ko-KR/tutorial/using-selenium-and-webdriver.md | 2 +- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index ec4cb74c253a..32412d13180b 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -92,7 +92,7 @@ Returns: 이 이벤트를 처리할 땐 반드시 `event.preventDefault()`를 호출해야 합니다. -Windows에선 `process.argv`를 통해 파일 경로를 얻을 수 있습니다. +Windows에선 `process.argv` (메인 프로세스에서)를 통해 파일 경로를 얻을 수 있습니다. ### Event: 'open-url' _OS X_ diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index f79b201d0a1d..f487a38f5da6 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -773,7 +773,7 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 아이콘입니다. `null`로 지정하면 빈 오버레이가 사용됩니다 * `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다 -현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. 보통 이 기능은 +현재 작업표시줄 아이콘에 16 x 16 픽셀 크기의 오버레이를 지정합니다. 보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. ### `win.setHasShadow(hasShadow)` _OS X_ diff --git a/docs-translations/ko-KR/api/clipboard.md b/docs-translations/ko-KR/api/clipboard.md index 2a0c98da2c09..df6475ad611b 100644 --- a/docs-translations/ko-KR/api/clipboard.md +++ b/docs-translations/ko-KR/api/clipboard.md @@ -62,6 +62,19 @@ console.log(clipboard.readText('selection')); 클립보드에 `image`를 씁니다. +### `clipboard.readRtf([type])` + +* `type` String (optional) + +클립보드로부터 RTF 형식으로 컨텐츠를 읽어옵니다. + +### `clipboard.writeRtf(text[, type])` + +* `text` String +* `type` String (optional) + +클립보드에 `text`를 RTF 형식으로 씁니다. + ### `clipboard.clear([type])` * `type` String (optional) diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index aba632430b52..12fac95bbeeb 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -17,7 +17,7 @@ 이벤트가 일어나면 `event` 객체와 임의의 인자와 함께 `callback` 함수가 호출됩니다. -### `ipcMain.removeListener(channel, callback)` +### `ipcRenderer.removeListener(channel, callback)` * `channel` String - 이벤트의 이름 * `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 @@ -26,15 +26,15 @@ 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. -### `ipcMain.removeAllListeners(channel)` +### `ipcRenderer.removeAllListeners(channel)` * `channel` String - 이벤트의 이름 이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. -### `ipcMain.once(channel, callback)` +### `ipcRenderer.once(channel, callback)` -`ipcMain.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. +`ipcRenderer.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. `callback`이 한 번 호출된 이후 활성화되지 않습니다. ## 메시지 보내기 diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 59eceb05a7a3..5598fb6eb260 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -293,23 +293,23 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c * `handler` Function * `webContents` Object - [WebContents](web-contents.md) 권한을 요청. * `permission` String - 'media', 'geolocation', 'notifications', - 'midiSysex'의 나열. + 'midiSysex', 'pointerLock', 'fullscreen'의 나열. * `callback` Function - 권한 허용 및 거부. `session`의 권한 요청에 응답을 하는데 사용하는 핸들러를 설정합니다. -`callback('granted')`를 호출하면 권한 제공을 허용하고 `callback('denied')`를 +`callback(true)`를 호출하면 권한 제공을 허용하고 `callback(false)`를 호출하면 권한 제공을 거부합니다. ```javascript session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { if (webContents.getURL() === host) { if (permission == "notifications") { - callback(); // 거부됨. + callback(false); // 거부됨. return; } } - callback('granted'); + callback(true); }); ``` diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index 635337574152..7072d7c4d952 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -59,9 +59,8 @@ electron/resources/ ### Windows -`electron.exe`을 원하는 이름으로 변경할 수 있습니다. -그리고 [rcedit](https://github.com/atom/rcedit) -를 사용하여 아이콘을 변경할 수 있습니다. +[rcedit](https://github.com/atom/rcedit)를 통해 `electron.exe`을 원하는 이름으로 +변경할 수 있고, 또한 아이콘과 기타 정보도 변경할 수 있습니다. ### OS X diff --git a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md index d0684e0cfe10..6cc5472bb12c 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -48,7 +48,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // 여기에 사용중인 Electron 바이너리의 경로를 지정하세요. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') From 17603d5dfbc7a98583e704502378c9867b26e999 Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Sun, 14 Feb 2016 19:13:11 -0800 Subject: [PATCH 035/132] makeSingleInstance clarification Removed callback return value from the sample code for makeSingleInstance because it appears to not be used for anything. --- docs/api/app.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index adba230b0e2b..5e56e970e1bc 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -398,7 +398,7 @@ quit. On OS X the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the `open-file` and `open-url` events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to +line the system's single instance mechanism will be bypassed and you have to use this method to ensure single instance. An example of activating the window of primary instance when a second instance @@ -413,7 +413,6 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) if (myWindow.isMinimized()) myWindow.restore(); myWindow.focus(); } - return true; }); if (shouldQuit) { From 2c6e5d046440081dea4f7ce66925796d820c1b44 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Fri, 12 Feb 2016 05:47:27 +0100 Subject: [PATCH 036/132] Clarify arguments sent via ipc --- docs/api/ipc-renderer.md | 2 +- docs/api/web-contents.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 96936632563e..d8f344a204a9 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -52,7 +52,7 @@ The `ipcRenderer` module has the following methods for sending messages: * `arg` (optional) Send an event to the main process asynchronously via a `channel`, you can also -send arbitrary arguments. The main process handles it by listening for the +send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The main process handles it by listening for the `channel` event with `ipcMain`. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index afdd08c4d005..61c2ab1f6919 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -693,7 +693,7 @@ Opens the developer tools for the service worker context. * `arg` (optional) Send an asynchronous message to renderer process via `channel`, you can also -send arbitrary arguments. The renderer process can handle the message by +send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The renderer process can handle the message by listening to the `channel` event with the `ipcRenderer` module. An example of sending messages from the main process to the renderer process: From a141d6b3d474fef058f5c152bb35e52597242926 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Mon, 15 Feb 2016 06:51:20 +0100 Subject: [PATCH 037/132] spelling fixes and americanisms --- docs/api/app.md | 4 ++-- docs/api/browser-window.md | 4 ++-- docs/api/web-view-tag.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index adba230b0e2b..4c806246e8fc 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -246,7 +246,7 @@ returning `false` in the `beforeunload` event handler. ### `app.hide()` _OS X_ -Hides all application windows without minimising them. +Hides all application windows without minimizing them. ### `app.show()` _OS X_ @@ -398,7 +398,7 @@ quit. On OS X the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the `open-file` and `open-url` events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to +line the system's single instance mechanism will be bypassed and you have to use this method to ensure single instance. An example of activating the window of primary instance when a second instance diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cf684a39539..25e1de729339 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -58,7 +58,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When - explicity set to `false` the fullscreen button will be hidden or disabled + explicitly set to `false` the fullscreen button will be hidden or disabled on OS X, or the maximize button will be disabled on Windows. Default is `false`. * `fullscreenable` Boolean - Whether the maximize/zoom button on OS X should @@ -717,7 +717,7 @@ Returns the pathname of the file the window represents. * `edited` Boolean Specifies whether the window’s document has been edited, and the icon in title -bar will become grey when set to `true`. +bar will become gray when set to `true`. ### `win.isDocumentEdited()` _OS X_ diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c410287553ac..6bdbb6826e8b 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -522,7 +522,7 @@ Returns: * `explicitSet` Boolean Fired when page title is set during navigation. `explicitSet` is false when -title is synthesised from file url. +title is synthesized from file url. ### Event: 'page-favicon-updated' From 7c7e6ffc77c8b074949c2e0f7422db1db5c21c68 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 15 Feb 2016 16:36:01 +0800 Subject: [PATCH 038/132] Fix broken links in desktop-environment-integration.md Close #4404. --- docs/tutorial/desktop-environment-integration.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 7d7eb44ecb6e..ac38f1088e73 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -294,15 +294,15 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 [tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx [notification-spec]: https://developer.gnome.org/notification-spec/ From 367a3524b9686791d5b19e3aab2181e4ebce4035 Mon Sep 17 00:00:00 2001 From: Prayag Verma Date: Tue, 16 Feb 2016 07:51:14 +0530 Subject: [PATCH 039/132] docs: fix a minor typo Remove extra `will` --- docs/api/content-tracing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index aae5306523ae..0b83c2759c67 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -155,7 +155,7 @@ called. * `eventName` String * `callback` Function -`callback` will will be called every time the given event occurs on any +`callback` will be called every time the given event occurs on any process. ### `contentTracing.cancelWatchEvent()` From ed1966ac760dcd2a7e80234c81319098bcf48ecb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 10:30:18 +0800 Subject: [PATCH 040/132] spec: Bring back beginFrameSubscription test --- spec/api-browser-window-spec.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 1c92d408c4c9..89e9b770ab20 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -478,10 +478,16 @@ describe('browser-window module', function() { }); }); - xdescribe('beginFrameSubscription method', function() { + describe('beginFrameSubscription method', function() { it('subscribes frame updates', function(done) { + let called = false; w.loadURL("file://" + fixtures + "/api/blank.html"); w.webContents.beginFrameSubscription(function(data) { + // This callback might be called twice. + if (called) + return; + called = true; + assert.notEqual(data.length, 0); w.webContents.endFrameSubscription(); done(); From 66bb6a85341f67dbeed92b1aa2a149fa1b84d18c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 10:44:10 +0800 Subject: [PATCH 041/132] Use weak pointer instead of manual bookkeeping --- atom/browser/api/atom_api_web_contents.cc | 8 ++--- atom/browser/api/frame_subscriber.cc | 40 +++-------------------- atom/browser/api/frame_subscriber.h | 30 +++++------------ 3 files changed, 16 insertions(+), 62 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1f441801407c..a7946786c514 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1072,11 +1072,9 @@ void WebContents::BeginFrameSubscription( const FrameSubscriber::FrameCaptureCallback& callback) { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { - FrameSubscriber* frame_subscriber = new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback); - scoped_ptr del_frame_subscriber( - frame_subscriber->GetSubscriber()); - view->BeginFrameSubscription(del_frame_subscriber.Pass()); + scoped_ptr frame_subscriber(new FrameSubscriber( + isolate(), view->GetVisibleViewportSize(), callback)); + view->BeginFrameSubscription(frame_subscriber.Pass()); } } diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 7d973892405c..b2b049ce8b74 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -13,58 +13,28 @@ namespace atom { namespace api { -using Subscriber = FrameSubscriber::Subscriber; - FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback), pending_frames(0) { - subscriber_ = new Subscriber(this); + : isolate_(isolate), size_(size), callback_(callback), weak_factory_(this) { } -Subscriber::Subscriber( - FrameSubscriber* frame_subscriber) : frame_subscriber_(frame_subscriber) { -} - -Subscriber::~Subscriber() { - frame_subscriber_->subscriber_ = NULL; - frame_subscriber_->RequestDestruct(); -} - -bool Subscriber::ShouldCaptureFrame( +bool FrameSubscriber::ShouldCaptureFrame( const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { *storage = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_YV12, - frame_subscriber_->size_, gfx::Rect(frame_subscriber_->size_), - frame_subscriber_->size_, base::TimeDelta()); + size_, gfx::Rect(size_), size_, base::TimeDelta()); *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - base::Unretained(frame_subscriber_), *storage); - frame_subscriber_->pending_frames++; + weak_factory_.GetWeakPtr(), *storage); return true; } -Subscriber* FrameSubscriber::GetSubscriber() { - return subscriber_; -} - -bool FrameSubscriber::RequestDestruct() { - bool deletable = (subscriber_ == NULL && pending_frames == 0); - // Destruct FrameSubscriber if we're not waiting for frames and the - // subscription has ended - if (deletable) - delete this; - - return deletable; -} - void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { - pending_frames--; - - if (RequestDestruct() || subscriber_ == NULL || !result) + if (!result) return; v8::Locker locker(isolate_); diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index 6f6d66b6be80..089c4922d797 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" @@ -14,43 +15,28 @@ namespace atom { namespace api { -class FrameSubscriber { +class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: using FrameCaptureCallback = base::Callback)>; - // Inner class that is the actual subscriber sent to chromium - class Subscriber : - public content::RenderWidgetHostViewFrameSubscriber { - public: - explicit Subscriber(FrameSubscriber* frame_subscriber); - - bool ShouldCaptureFrame(const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) override; - - ~Subscriber(); - private: - FrameSubscriber* frame_subscriber_; - }; - FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback); - Subscriber* GetSubscriber(); + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; private: void OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool); - bool RequestDestruct(); - v8::Isolate* isolate_; gfx::Size size_; FrameCaptureCallback callback_; - Subscriber* subscriber_; - int pending_frames; + + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); }; From 3c4043fd3968a2c153b978251de3e84d4f58ace9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:00:36 +0800 Subject: [PATCH 042/132] spec: Skip autoUpdater tests in MAS build --- spec/api-auto-updater-spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/api-auto-updater-spec.js b/spec/api-auto-updater-spec.js index 72a1d90a7fe4..efd3afe3882f 100644 --- a/spec/api-auto-updater-spec.js +++ b/spec/api-auto-updater-spec.js @@ -2,6 +2,10 @@ const assert = require('assert'); const autoUpdater = require('electron').remote.autoUpdater; const ipcRenderer = require('electron').ipcRenderer; +// Skip autoUpdater tests in MAS build. +if (process.mas) + return; + describe('autoUpdater module', function() { describe('checkForUpdates', function() { it('emits an error on Windows when called the feed URL is not set', function (done) { From 2aff0c47d03458947dad5866069523fca717042f Mon Sep 17 00:00:00 2001 From: cesine Date: Mon, 15 Feb 2016 21:26:25 -0500 Subject: [PATCH 043/132] :arrow_up: :shirt: updated to eslint 2.1.0 Verified migration doc (nothing to be done) http://eslint.org/docs/user-guide/migrating-to-2.0.0 And made sure the eslint tasks passed --- atom/browser/lib/rpc-server.js | 6 ++++-- package.json | 2 +- spec/asar-spec.js | 1 - spec/fixtures/api/quit-app/main.js | 12 ++++++------ spec/fixtures/module/call.js | 4 ++-- spec/fixtures/module/id.js | 2 +- spec/fixtures/module/locale-compare.js | 2 +- spec/fixtures/module/original-fs.js | 2 +- spec/fixtures/module/print_name.js | 4 ++-- spec/fixtures/module/promise.js | 2 +- spec/fixtures/module/property.js | 2 +- spec/fixtures/module/send-later.js | 2 +- spec/fixtures/module/set-immediate.js | 2 +- spec/fixtures/workers/shared_worker.js | 6 +++--- spec/fixtures/workers/worker.js | 2 +- spec/static/main.js | 4 ++-- 16 files changed, 28 insertions(+), 27 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 2f2b739e4a14..976a42331b6a 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -130,7 +130,7 @@ var unwrapArgs = function(sender, args) { return Promise.resolve({ then: metaToValue(meta.then) }); - case 'object': + case 'object': { let ret = v8Util.createObjectWithName(meta.name); ref = meta.members; for (i = 0, len = ref.length; i < len; i++) { @@ -138,12 +138,13 @@ var unwrapArgs = function(sender, args) { ret[member.name] = metaToValue(member.value); } return ret; + } case 'function-with-return-value': returnValue = metaToValue(meta.value); return function() { return returnValue; }; - case 'function': + case 'function': { // Cache the callbacks in renderer. if (!sender.callbacks) { sender.callbacks = new IDWeakMap; @@ -172,6 +173,7 @@ var unwrapArgs = function(sender, args) { }); sender.callbacks.set(meta.id, callIntoRenderer); return callIntoRenderer; + } default: throw new TypeError("Unknown type: " + meta.type); } diff --git a/package.json b/package.json index 6d8120871991..f684386269e2 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.36.7", "devDependencies": { "asar": "^0.9.0", - "eslint": "^1.10.3", + "eslint": "^2.1.0", "request": "*" }, "optionalDependencies": { diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 81d881f7eb40..a8f449451fcf 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -517,7 +517,6 @@ describe('asar package', function() { }); }); describe('child_process.fork', function() { - child_process = require('child_process'); it('opens a normal js file', function(done) { var child; child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); diff --git a/spec/fixtures/api/quit-app/main.js b/spec/fixtures/api/quit-app/main.js index e2f97affe6de..114e830076a0 100644 --- a/spec/fixtures/api/quit-app/main.js +++ b/spec/fixtures/api/quit-app/main.js @@ -1,12 +1,12 @@ -var app = require('electron').app +var app = require('electron').app; app.on('ready', function () { // This setImmediate call gets the spec passing on Linux setImmediate(function () { - app.exit(123) - }) -}) + app.exit(123); + }); +}); process.on('exit', function (code) { - console.log('Exit event with code: ' + code) -}) + console.log('Exit event with code: ' + code); +}); diff --git a/spec/fixtures/module/call.js b/spec/fixtures/module/call.js index 4cf232e220de..ce0eb6324df4 100644 --- a/spec/fixtures/module/call.js +++ b/spec/fixtures/module/call.js @@ -1,7 +1,7 @@ exports.call = function(func) { return func(); -} +}; exports.constructor = function() { this.test = 'test'; -} +}; diff --git a/spec/fixtures/module/id.js b/spec/fixtures/module/id.js index 2faec9d38321..5bfae457fe0b 100644 --- a/spec/fixtures/module/id.js +++ b/spec/fixtures/module/id.js @@ -1 +1 @@ -exports.id = 1127 +exports.id = 1127; diff --git a/spec/fixtures/module/locale-compare.js b/spec/fixtures/module/locale-compare.js index f99e7c3be119..32dfb309926b 100644 --- a/spec/fixtures/module/locale-compare.js +++ b/spec/fixtures/module/locale-compare.js @@ -1,4 +1,4 @@ -process.on('message', function (msg) { +process.on('message', function () { process.send([ 'a'.localeCompare('a'), 'ä'.localeCompare('z', 'de'), diff --git a/spec/fixtures/module/original-fs.js b/spec/fixtures/module/original-fs.js index 90b6abcf9b78..7a527c633585 100644 --- a/spec/fixtures/module/original-fs.js +++ b/spec/fixtures/module/original-fs.js @@ -1,3 +1,3 @@ -process.on('message', function (msg) { +process.on('message', function () { process.send(typeof require('original-fs')); }); diff --git a/spec/fixtures/module/print_name.js b/spec/fixtures/module/print_name.js index 01d13f4ba8bf..96ac2d6f3cb5 100644 --- a/spec/fixtures/module/print_name.js +++ b/spec/fixtures/module/print_name.js @@ -1,7 +1,7 @@ exports.print = function(obj) { return obj.constructor.name; -} +}; exports.echo = function(obj) { return obj; -} +}; diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js index 2e52ed374400..b9b568855e30 100644 --- a/spec/fixtures/module/promise.js +++ b/spec/fixtures/module/promise.js @@ -2,4 +2,4 @@ exports.twicePromise = function (promise) { return promise.then(function (value) { return value * 2; }); -} +}; diff --git a/spec/fixtures/module/property.js b/spec/fixtures/module/property.js index 88e596f73083..36286d800e16 100644 --- a/spec/fixtures/module/property.js +++ b/spec/fixtures/module/property.js @@ -1 +1 @@ -exports.property = 1127 +exports.property = 1127; diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js index 13f02452db1c..704f47d328df 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ var ipcRenderer = require('electron').ipcRenderer; window.onload = function() { ipcRenderer.send('answer', typeof window.process); -} +}; diff --git a/spec/fixtures/module/set-immediate.js b/spec/fixtures/module/set-immediate.js index e7d44a75d1fe..d36355ee23b4 100644 --- a/spec/fixtures/module/set-immediate.js +++ b/spec/fixtures/module/set-immediate.js @@ -3,7 +3,7 @@ process.on('uncaughtException', function(error) { process.exit(1); }); -process.on('message', function(msg) { +process.on('message', function() { setImmediate(function() { process.send('ok'); process.exit(0); diff --git a/spec/fixtures/workers/shared_worker.js b/spec/fixtures/workers/shared_worker.js index d35b47435e8a..402207939793 100644 --- a/spec/fixtures/workers/shared_worker.js +++ b/spec/fixtures/workers/shared_worker.js @@ -1,7 +1,7 @@ -onconnect = function(event) { +this.onconnect = function(event) { var port = event.ports[0]; port.start(); port.onmessage = function(event) { port.postMessage(event.data); - } -} + }; +}; diff --git a/spec/fixtures/workers/worker.js b/spec/fixtures/workers/worker.js index 6f9533708a0d..4f445470b9ad 100644 --- a/spec/fixtures/workers/worker.js +++ b/spec/fixtures/workers/worker.js @@ -1,3 +1,3 @@ this.onmessage = function(msg) { this.postMessage(msg.data); -} +}; diff --git a/spec/static/main.js b/spec/static/main.js index 125ef72f609c..48fdf17c3dcf 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -74,7 +74,7 @@ app.on('ready', function() { // Send auto updater errors to window to be verified in specs electron.autoUpdater.on('error', function (error) { - window.send('auto-updater-error', error.message) + window.send('auto-updater-error', error.message); }); window = new BrowserWindow({ @@ -108,7 +108,7 @@ app.on('ready', function() { // reply the result to renderer for verifying var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); ipcMain.on('set-download-option', function(event, need_cancel, prevent_default) { - window.webContents.session.once('will-download', function(e, item, webContents) { + window.webContents.session.once('will-download', function(e, item) { if (prevent_default) { e.preventDefault(); const url = item.getURL(); From b8e8e4c930b3d06a2ae71f995b8b329ea41bd545 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:34:39 +0800 Subject: [PATCH 044/132] docs: Cleanup the IPC docs --- docs/api/ipc-main.md | 46 +++++++++++++++--------------- docs/api/ipc-renderer.md | 61 +++++++++++++++++++++------------------- docs/api/web-contents.md | 7 +++-- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 337d86be217b..84fbcfd5a72f 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -9,7 +9,7 @@ module. ## Sending Messages It is also possible to send messages from the main process to the renderer -process, see [webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-) for more information. +process, see [webContents.send][web-contents-send] for more information. * When sending a message, the event name is the `channel`. * To reply a synchronous message, you need to set `event.returnValue`. @@ -48,37 +48,37 @@ ipcRenderer.send('asynchronous-message', 'ping'); The `ipcMain` module has the following method to listen for events: -### `ipcMain.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - The event name. -* `callback` Function +* `channel` String +* `listener` Function -When the event occurs the `callback` is called with an `event` object and -arbitrary arguments. +Listens to `channel`, when a new message arrives `listener` would be called with +`listener(event, args...)`. -### `ipcMain.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - The event name. -* `callback` Function - The reference to the same function that you used for - `ipcMain.on(channel, callback)` +* `channel` String +* `listener` Function -Once done listening for messages, if you no longer want to activate this -callback and for whatever reason can't merely stop sending messages on the -channel, this function will remove the callback handler for the specified -channel. +Adds a one time `listener` function for the event. This `listener` is invoked +only the next time a message is sent to `channel`, after which it is removed. -### `ipcMain.removeAllListeners(channel)` +### `ipcMain.removeListener(channel, listener)` -* `channel` String - The event name. +* `channel` String +* `listener` Function -This removes *all* handlers to this ipc channel. +Removes the specified `listener` from the listener array for the specified +`channel`. -### `ipcMain.once(channel, callback)` +### `ipcMain.removeAllListeners([channel])` -Use this in place of `ipcMain.on()` to fire handlers meant to occur only once, -as in, they won't be activated after one call of `callback` +* `channel` String (optional) -## IPC Event +Removes all listeners, or those of the specified `channel`. + +## Event object The `event` object passed to the `callback` has the following methods: @@ -90,4 +90,6 @@ Set this to the value to be returned in a synchronous message. Returns the `webContents` that sent the message, you can call `event.sender.send` to reply to the asynchronous message, see -[webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-) for more information. +[webContents.send][web-contents-send] for more information. + +[web-contents-send]: web-contents.md#webcontentssendchannel-arg1-arg2- diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index d8f344a204a9..f17843702b57 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -12,35 +12,35 @@ See [ipcMain](ipc-main.md) for code examples. The `ipcRenderer` module has the following method to listen for events: -### `ipcRenderer.on(channel, callback)` +### `ipcRenderer.on(channel, listener)` -* `channel` String - The event name. -* `callback` Function +* `channel` String +* `listener` Function -When the event occurs the `callback` is called with an `event` object and -arbitrary arguments. +Listens to `channel`, when a new message arrives `listener` would be called with +`listener(event, args...)`. -### `ipcRenderer.removeListener(channel, callback)` +### `ipcRenderer.once(channel, listener)` -* `channel` String - The event name. -* `callback` Function - The reference to the same function that you used for - `ipcRenderer.on(channel, callback)` +* `channel` String +* `listener` Function -Once done listening for messages, if you no longer want to activate this -callback and for whatever reason can't merely stop sending messages on the -channel, this function will remove the callback handler for the specified -channel. +Adds a one time `listener` function for the event. This `listener` is invoked +only the next time a message is sent to `channel`, after which it is removed. -### `ipcRenderer.removeAllListeners(channel)` +### `ipcRenderer.removeListener(channel, listener)` -* `channel` String - The event name. +* `channel` String +* `listener` Function -This removes *all* handlers to this ipc channel. +Removes the specified `listener` from the listener array for the specified +`channel`. -### `ipcRenderer.once(channel, callback)` +### `ipcRenderer.removeAllListeners([channel])` -Use this in place of `ipcRenderer.on()` to fire handlers meant to occur only once, -as in, they won't be activated after one call of `callback` +* `channel` String (optional) + +Removes all listeners, or those of the specified `channel`. ## Sending Messages @@ -48,30 +48,33 @@ The `ipcRenderer` module has the following methods for sending messages: ### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) -Send an event to the main process asynchronously via a `channel`, you can also -send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The main process handles it by listening for the -`channel` event with `ipcMain`. +Send a message to the main process asynchronously via `channel`, you can also +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. + +The main process handles it by listening for `channel` with `ipcMain` module. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) -Send an event to the main process synchronously via a `channel`, you can also -send arbitrary arguments. +Send a message to the main process synchronously via `channel`, you can also +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. -The main process handles it by listening for the `channel` event with -`ipcMain` and replies by setting `event.returnValue`. +The main process handles it by listening for `channel` with `ipcMain` module, +and replies by setting `event.returnValue`. __Note:__ Sending a synchronous message will block the whole renderer process, unless you know what you are doing you should never use it. ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) Like `ipcRenderer.send` but the event will be sent to the `` element in diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 61c2ab1f6919..b868bea9ed5e 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -693,8 +693,11 @@ Opens the developer tools for the service worker context. * `arg` (optional) Send an asynchronous message to renderer process via `channel`, you can also -send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The renderer process can handle the message by -listening to the `channel` event with the `ipcRenderer` module. +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. + +The renderer process can handle the message by listening to `channel` with the +`ipcRenderer` module. An example of sending messages from the main process to the renderer process: From f58bab70c5146d63583af9179941d87fe11d7e60 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:52:47 +0800 Subject: [PATCH 045/132] docs: Improve the docs on sharing data --- docs/faq/electron-faq.md | 40 +++++++++++++++++------------------- docs/tutorial/quick-start.md | 18 ++++++++-------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index d5470f701734..a58d31107b6d 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -18,40 +18,34 @@ New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron. -## What are the different techniques to share objects between web pages? +## How to share data between web pages? -To share objects between web pages (that is on the renderer side) the simplest -and more natural technique is to use a web standard API already available in all -browsers. A good candidate is the -[Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage), -through either the -[`window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) property or the -[`window.sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) property. -Note that the Storage API allows only to store strings, so objects must be -serialized as JSON. -Another candidate is -[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). +To share data between web pages (the renderer processes) the simplest way is to +use HTML5 APIs which are already available in browsers. Good candidates are +[Storage API][storage], [`localStorage`][local-storage], +[`sessionStorage`][session-storage], and [IndexedDB][indexed-db]. -Another technique, but this time specific to Electron, is to store objects in -the main process as a global variable and then to access them from the renderers -through the `remote` module: +Or you can use the IPC system, which are specific to Electron, to store objects +in the main process as a global variable, and then to access them from the +renderers through the `remote` module: ```javascript -// In main.js of browser process -global.sharedObject = {}; +// In the main process. +global.sharedObject = { + someProperty: 'default value' +}; ``` ```javascript -// js in page-1.html -require('remote').getGlobal('sharedObject').someProperty = 'some value'; +// In page 1. +require('remote').getGlobal('sharedObject').someProperty = 'new value'; ``` ```javascript -// js in page-2.html +// In page 2. console.log(require('remote').getGlobal('sharedObject').someProperty); ``` - ## My app's window/tray disappeared after a few minutes. This happens when the variable which is used to store the window/tray gets @@ -154,3 +148,7 @@ is only available in renderer processes. [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 67fe5d608a13..684c72c6669e 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -34,8 +34,8 @@ The main process creates web pages by creating `BrowserWindow` instances. Each is also terminated. The main process manages all web pages and their corresponding renderer -processes. Each renderer process is isolated and only cares -about the web page running in it. +processes. Each renderer process is isolated and only cares about the web page +running in it. In web pages, calling native GUI related APIs is not allowed because managing native GUI resources in web pages is very dangerous and it is easy to leak @@ -43,13 +43,11 @@ resources. If you want to perform GUI operations in a web page, the renderer process of the web page must communicate with the main process to request that the main process perform those operations. -In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for -communication between the main process and renderer process. There is also a -[remote](../api/remote.md) module for RPC style communication. - -And finally there are different techniques [to share objects between web -pages](../faq/electron-faq.md#what-are-the-different-techniques-to-share-objects-between-web-pages) -of the same window or of different windows. +In Electron, we have several ways to communicate between the main process and +renderer processes. Like [`ipcRenderer`](../api/ipc-renderer.md) and +[`ipcMain`](../api/ipc-main.md) modules for sending messages, and the +[remote](../api/remote.md) module for RPC style communication. There is also +an FAQ entry on [how to share data between web pages][share-data]. ## Write your First Electron App @@ -209,3 +207,5 @@ $ cd electron-quick-start # Install dependencies and run the app $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#how-to-share-data-between-web-pages From 2b406ccaf751bb2541b1924aae8204863bab6d4f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:54:41 +0800 Subject: [PATCH 046/132] Optional => optional --- docs/api/web-contents.md | 6 +++--- docs/api/web-view-tag.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index b868bea9ed5e..c243425c5d9f 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -259,8 +259,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. - * `matches` Integer (Optional) - Number of Matches. - * `selectionArea` Object (Optional) - Coordinates of first match region. + * `matches` Integer (optional) - Number of Matches. + * `selectionArea` Object (optional) - Coordinates of first match region. Emitted when a result is available for [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) request. @@ -503,7 +503,7 @@ Inserts `text` to the focused element. ### `webContents.findInPage(text[, options])` * `text` String - Content to be searched, must not be empty. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - Whether to search forward or backward, defaults to `true`. * `findNext` Boolean - Whether the operation is first request or a follow up, defaults to `false`. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c410287553ac..976f859efca3 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -382,7 +382,7 @@ Inserts `text` to the focused element. ### `.findInPage(text[, options])` * `text` String - Content to be searched, must not be empty. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - Whether to search forward or backward, defaults to `true`. * `findNext` Boolean - Whether the operation is first request or a follow up, defaults to `false`. @@ -567,8 +567,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. - * `matches` Integer (Optional) - Number of Matches. - * `selectionArea` Object (Optional) - Coordinates of first match region. + * `matches` Integer (optional) - Number of Matches. + * `selectionArea` Object (optional) - Coordinates of first match region. Fired when a result is available for [`webview.findInPage`](web-view-tag.md#webviewtagfindinpage) request. From fded8d80b118fa39cb5fd225e4412434f0bb31ee Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 12:11:05 +0800 Subject: [PATCH 047/132] docs: Remove unnecessary "properties: " suffix --- docs/api/browser-window.md | 53 +++++++++++++++++++------------------- docs/api/crash-reporter.md | 23 +++++++---------- docs/api/web-contents.md | 46 +++++++++++++-------------------- docs/api/web-view-tag.md | 2 +- 4 files changed, 56 insertions(+), 68 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cf684a39539..2bd6c1a9635c 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -458,7 +458,7 @@ Returns a boolean, whether the window is in fullscreen mode. * `aspectRatio` The aspect ratio we want to maintain for some portion of the content view. * `extraSize` Object (optional) - The extra size not to be included while -maintaining the aspect ratio. Properties: +maintaining the aspect ratio. * `width` Integer * `height` Integer @@ -478,13 +478,11 @@ height areas you have within the overall content view. ### `win.setBounds(options[, animate])` -* `options` Object, properties: - +* `options` Object * `x` Integer * `y` Integer * `width` Integer * `height` Integer - * `animate` Boolean (optional) _OS X_ Resizes and moves the window to `width`, `height`, `x`, `y`. @@ -729,7 +727,7 @@ Whether the window's document has been edited. ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional)- The area of page to be captured, properties: +* `rect` Object (optional) - The area of page to be captured * `x` Integer * `y` Integer * `width` Integer @@ -802,27 +800,7 @@ Returns whether the window has a shadow. On Windows and Linux always returns ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` Array of `button` Objects: - -`button` Object, properties: - -* `icon` [NativeImage](native-image.md) - The icon showing in thumbnail - toolbar. -* `tooltip` String (optional) - The text of the button's tooltip. -* `flags` Array (optional) - Control specific states and behaviors - of the button. By default, it uses `enabled`. It can include following - Strings: - * `enabled` - The button is active and available to the user. - * `disabled` - The button is disabled. It is present, but has a visual - state indicating it will not respond to user action. - * `dismissonclick` - When the button is clicked, the taskbar button's - flyout closes immediately. - * `nobackground` - Do not draw a button border, use only the image. - * `hidden` - The button is not shown to the user. - * `noninteractive` - The button is enabled but not interactive; no - pressed button state is drawn. This value is intended for instances - where the button is used in a notification. -* `click` - Function +* `buttons` Array Add a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a taskbar button layout. Returns a `Boolean` object indicates @@ -833,6 +811,29 @@ the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be removed due to the platform's limitation. But you can call the API with an empty array to clean the buttons. +The `buttons` is an array of `Button` objects: + +* `Button` Object + * `icon` [NativeImage](native-image.md) - The icon showing in thumbnail + toolbar. + * `click` Function + * `tooltip` String (optional) - The text of the button's tooltip. + * `flags` Array (optional) - Control specific states and behaviors of the + button. By default, it is `['enabled']`. + +The `flags` is an array that can include following `String`s: + +* `enabled` - The button is active and available to the user. +* `disabled` - The button is disabled. It is present, but has a visual state + indicating it will not respond to user action. +* `dismissonclick` - When the button is clicked, the thumbnail window closes + immediately. +* `nobackground` - Do not draw a button border, use only the image. +* `hidden` - The button is not shown to the user. +* `noninteractive` - The button is enabled but not interactive; no pressed + button state is drawn. This value is intended for instances where the button + is used in a notification. + ### `win.showDefinitionForSelection()` _OS X_ Shows pop-up dictionary that searches the selected word on the page. diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 1b0928263566..98465dffc971 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -22,19 +22,16 @@ The `crash-reporter` module has the following methods: ### `crashReporter.start(options)` -`options` Object, properties: - -* `productName` String, default: Electron. -* `companyName` String (**required**) -* `submitURL` String, (**required**) - * URL that crash reports will be sent to as POST. -* `autoSubmit` Boolean, default: `true`. - * Send the crash report without user interaction. -* `ignoreSystemCrashHandler` Boolean, default: `false`. -* `extra` Object - * An object you can define that will be sent along with the report. - * Only string properties are sent correctly. - * Nested objects are not supported. +* `options` Object + * `companyName` String + * `submitURL` String - URL that crash reports will be sent to as POST. + * `productName` String (optional) - Default is `Electron`. + * `autoSubmit` Boolean - Send the crash report without user interaction. + Default is `true`. + * `ignoreSystemCrashHandler` Boolean - Default is `false`. + * `extra` Object - An object you can define that will be sent along with the + report. Only string properties are sent correctly, Nested objects are not + supported. You are required to call this method before using other `crashReporter` APIs. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index c243425c5d9f..e0139a29fa6c 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -310,7 +310,7 @@ The `webContents` object has the following instance methods: ### `webContents.loadURL(url[, options])` * `url` URL -* `options` Object (optional), properties: +* `options` Object (optional) * `httpReferrer` String - A HTTP Referrer url. * `userAgent` String - A user agent originating the request. * `extraHeaders` String - Extra headers separated by "\n" @@ -556,11 +556,10 @@ when the JS promise is rejected. ### `webContents.print([options])` -`options` Object (optional), properties: - -* `silent` Boolean - Don't ask user for print settings, defaults to `false` -* `printBackground` Boolean - Also prints the background color and image of - the web page, defaults to `false`. +* `options` Object (optional) + * `silent` Boolean - Don't ask user for print settings. Default is `false`. + * `printBackground` Boolean - Also prints the background color and image of + the web page. Default is `false`. Prints window's web page. When `silent` is set to `false`, Electron will pick up system's default printer and default settings for printing. @@ -574,31 +573,22 @@ size. ### `webContents.printToPDF(options, callback)` -`options` Object, properties: - -* `marginsType` Integer - Specify the type of margins to use - * 0 - default - * 1 - none - * 2 - minimum -* `pageSize` String - Specify page size of the generated PDF. - * `A5` - * `A4` - * `A3` - * `Legal` - * `Letter` - * `Tabloid` -* `printBackground` Boolean - Whether to print CSS backgrounds. -* `printSelectionOnly` Boolean - Whether to print selection only. -* `landscape` Boolean - `true` for landscape, `false` for portrait. - -`callback` Function - `function(error, data) {}` - -* `error` Error -* `data` Buffer - PDF file content. +* `options` Object + * `marginsType` Integer - Specifies the type of margins to use. Uses 0 for + default margin, 1 for no margin, and 2 for minimum margin. + * `pageSize` String - Specify page size of the generated PDF. Can be `A3`, + `A4`, `A5`, `Legal`, `Letter` and `Tabloid`. + * `printBackground` Boolean - Whether to print CSS backgrounds. + * `printSelectionOnly` Boolean - Whether to print selection only. + * `landscape` Boolean - `true` for landscape, `false` for portrait. +* `callback` Function Prints window's web page as PDF with Chromium's preview printing custom settings. +The `callback` will be called with `callback(error, data)` on completion. The +`data` is a `Buffer` that contains the generated PDF data. + By default, an empty `options` will be regarded as: ```javascript @@ -651,7 +641,7 @@ Removes the specified path from DevTools workspace. ### `webContents.openDevTools([options])` -* `options` Object (optional). Properties: +* `options` Object (optional) * `detach` Boolean - opens DevTools in a new window Opens the devtools. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 976f859efca3..3ba9a602e8be 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -184,7 +184,7 @@ webview.addEventListener("dom-ready", function() { ### `.loadURL(url[, options])` * `url` URL -* `options` Object (optional), properties: +* `options` Object (optional) * `httpReferrer` String - A HTTP Referrer url. * `userAgent` String - A user agent originating the request. * `extraHeaders` String - Extra headers separated by "\n" From 81ffde3c2a88f7f2bc25532b97a26e96cc28432e Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 16 Feb 2016 09:55:59 +0900 Subject: [PATCH 048/132] :memo: Update as upstream [ci skip] --- .../desktop-environment-integration.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index 91fc59a8f2ef..cd6ff545e14d 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -283,13 +283,15 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons -[trayballoon]: ../api/tray.md#traydisplayballoonoptions-windows +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 +[tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[notification-spec]: https://developer.gnome.org/notification-spec/ From aaca93046c5a6d0a16880ac0bc17c6890c57ffa9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 16:20:15 +0800 Subject: [PATCH 049/132] spec: Give beginFrameSubscription test more time to run --- spec/api-browser-window-spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index a38bdb16904d..b64ef6145b78 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -480,6 +480,8 @@ describe('browser-window module', function() { }); describe('beginFrameSubscription method', function() { + this.timeout(20000); + it('subscribes frame updates', function(done) { let called = false; w.loadURL("file://" + fixtures + "/api/blank.html"); From afacca252e21804a4351570de7a7e879c95b5753 Mon Sep 17 00:00:00 2001 From: Destan Sarpkaya Date: Tue, 16 Feb 2016 16:24:05 +0200 Subject: [PATCH 050/132] add a new platform definition for linux On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again Regarding https://github.com/atom/electron/issues/1473 --- docs/api/tray.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/tray.md b/docs/api/tray.md index 08a43638be14..3d6f94ad0e5a 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -32,6 +32,12 @@ __Platform limitations:__ install `libappindicator1` to make the tray icon work. * App indicator will only be shown when it has a context menu. * When app indicator is used on Linux, the `click` event is ignored. +* On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again. For example: + +```javascript +appIcon.menu.items[2].checked = false; +appIcon.setContextMenu(trayIcon.menu); +``` If you want to keep exact same behaviors on all platforms, you should not rely on the `click` event and always attach a context menu to the tray icon. From 0ba86b971633399b7d18086fdce1389718198f43 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 23:10:05 +0800 Subject: [PATCH 051/132] docs: Make variable names follow previous example --- docs/api/tray.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 3d6f94ad0e5a..22ab9aea5b79 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -32,11 +32,12 @@ __Platform limitations:__ install `libappindicator1` to make the tray icon work. * App indicator will only be shown when it has a context menu. * When app indicator is used on Linux, the `click` event is ignored. -* On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again. For example: +* On Linux in order for changes made to individual `MenuItem`s to take effect, + you have to call `setContextMenu` again. For example: ```javascript -appIcon.menu.items[2].checked = false; -appIcon.setContextMenu(trayIcon.menu); +contextMenu.items[2].checked = false; +appIcon.setContextMenu(contextMenu); ``` If you want to keep exact same behaviors on all platforms, you should not From 959c08a1ecdc31bb7c39ff3a4fcdf0c59bfbe50b Mon Sep 17 00:00:00 2001 From: dmnlk Date: Wed, 17 Feb 2016 02:20:38 +0900 Subject: [PATCH 052/132] add Japanese Electron Community --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ce6d483f0dff..0080585b54cd 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ forums - [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* +- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)* Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources. From 2346caf6fbb691b7a2c7fe73e363344f371a8027 Mon Sep 17 00:00:00 2001 From: Seemann Date: Tue, 16 Feb 2016 23:19:20 +0300 Subject: [PATCH 053/132] fixed typo in the russian translation of README.md --- docs-translations/ru-RU/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ru-RU/README.md b/docs-translations/ru-RU/README.md index 07e50028df94..4e7ed443468a 100644 --- a/docs-translations/ru-RU/README.md +++ b/docs-translations/ru-RU/README.md @@ -1,6 +1,6 @@ Пожалуйста, убедитесь, что вы используете документацию, которые соответствует вашей версии Electron. Номер версии должен быть частью адреса страницы. Если это не так, вы -возможно,используете документицию ветки разработки, которая может содержать изменения api, +возможно, используете документацию ветки разработки, которая может содержать изменения api, которые не совместимы с вашей версией Electron. Если это так, Вы можете переключиться на другую версию документации в списке [доступные версии](http://electron.atom.io/docs/) на atom.io, или From ccef805e9b85c4e17114e68cb14070c98e8a166c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 16 Feb 2016 15:09:35 -0800 Subject: [PATCH 054/132] Add API for custom handling of deprecations --- atom/common/api/lib/deprecate.js | 14 ++++++++++++- atom/common/api/lib/deprecations.js | 11 ++++++++++ atom/common/api/lib/exports/electron.js | 6 ++++++ filenames.gypi | 1 + spec/api-deprecations-spec.js | 27 +++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 atom/common/api/lib/deprecations.js create mode 100644 spec/api-deprecations-spec.js diff --git a/atom/common/api/lib/deprecate.js b/atom/common/api/lib/deprecate.js index dcaf5f6cf6f9..04b56e06b96d 100644 --- a/atom/common/api/lib/deprecate.js +++ b/atom/common/api/lib/deprecate.js @@ -88,9 +88,13 @@ deprecate.warn = function(oldName, newName) { return deprecate.log(oldName + " is deprecated. Use " + newName + " instead."); }; +var deprecationHandler = null; + // Print deprecation message. deprecate.log = function(message) { - if (process.throwDeprecation) { + if (typeof deprecationHandler === 'function') { + deprecationHandler(message); + } else if (process.throwDeprecation) { throw new Error(message); } else if (process.traceDeprecation) { return console.trace(message); @@ -99,4 +103,12 @@ deprecate.log = function(message) { } }; +deprecate.setHandler = function(handler) { + deprecationHandler = handler; +}; + +deprecate.getHandler = function() { + return deprecationHandler; +} + module.exports = deprecate; diff --git a/atom/common/api/lib/deprecations.js b/atom/common/api/lib/deprecations.js new file mode 100644 index 000000000000..871ad0362721 --- /dev/null +++ b/atom/common/api/lib/deprecations.js @@ -0,0 +1,11 @@ +'use strict'; + +const deprecate = require('electron').deprecate; + +exports.setHandler = function (deprecationHandler) { + deprecate.setHandler(deprecationHandler); +}; + +exports.getHandler = function () { + return deprecate.getHandler(); +} diff --git a/atom/common/api/lib/exports/electron.js b/atom/common/api/lib/exports/electron.js index 6811e73a10b6..51ab48ded833 100644 --- a/atom/common/api/lib/exports/electron.js +++ b/atom/common/api/lib/exports/electron.js @@ -31,6 +31,12 @@ exports.defineProperties = function(exports) { return require('../crash-reporter'); } }, + deprecations: { + enumerable: true, + get: function() { + return require('../deprecations'); + } + }, nativeImage: { enumerable: true, get: function() { diff --git a/filenames.gypi b/filenames.gypi index a5369570cade..abb114532106 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -41,6 +41,7 @@ 'atom/common/api/lib/clipboard.js', 'atom/common/api/lib/crash-reporter.js', 'atom/common/api/lib/deprecate.js', + 'atom/common/api/lib/deprecations.js', 'atom/common/api/lib/exports/electron.js', 'atom/common/api/lib/native-image.js', 'atom/common/api/lib/shell.js', diff --git a/spec/api-deprecations-spec.js b/spec/api-deprecations-spec.js new file mode 100644 index 000000000000..282991a6858f --- /dev/null +++ b/spec/api-deprecations-spec.js @@ -0,0 +1,27 @@ +const assert = require('assert'); +const deprecations = require('electron').deprecations; + +describe('deprecations', function() { + beforeEach(function() { + deprecations.setHandler(null); + process.throwDeprecation = true; + }); + + it('allows a deprecation handler function to be specified', function() { + var messages = []; + + deprecations.setHandler(function (message) { + messages.push(message) + }); + + require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme') + + assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']); + }); + + it('throws an exception if no deprecation handler is specified', function() { + assert.throws(function() { + require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme') + }, "registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead."); + }); +}) From 3e3e59336600c88ebb5220c5be35fd3c07549878 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 16 Feb 2016 15:26:58 -0800 Subject: [PATCH 055/132] :shirt: Add missing semicolons --- atom/common/api/lib/deprecate.js | 2 +- atom/common/api/lib/deprecations.js | 2 +- spec/api-deprecations-spec.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/common/api/lib/deprecate.js b/atom/common/api/lib/deprecate.js index 04b56e06b96d..852d544deea9 100644 --- a/atom/common/api/lib/deprecate.js +++ b/atom/common/api/lib/deprecate.js @@ -109,6 +109,6 @@ deprecate.setHandler = function(handler) { deprecate.getHandler = function() { return deprecationHandler; -} +}; module.exports = deprecate; diff --git a/atom/common/api/lib/deprecations.js b/atom/common/api/lib/deprecations.js index 871ad0362721..e4290c749474 100644 --- a/atom/common/api/lib/deprecations.js +++ b/atom/common/api/lib/deprecations.js @@ -8,4 +8,4 @@ exports.setHandler = function (deprecationHandler) { exports.getHandler = function () { return deprecate.getHandler(); -} +}; diff --git a/spec/api-deprecations-spec.js b/spec/api-deprecations-spec.js index 282991a6858f..2f0100590598 100644 --- a/spec/api-deprecations-spec.js +++ b/spec/api-deprecations-spec.js @@ -11,17 +11,17 @@ describe('deprecations', function() { var messages = []; deprecations.setHandler(function (message) { - messages.push(message) + messages.push(message); }); - require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme') + require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme'); assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']); }); it('throws an exception if no deprecation handler is specified', function() { assert.throws(function() { - require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme') + require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme'); }, "registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead."); }); -}) +}); From 407bef5727a8bf36fd011d4e6e6800386b236ac3 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 17 Feb 2016 00:40:35 +0900 Subject: [PATCH 056/132] :memo: Update as upstream [ci skip] --- README-ko.md | 1 + docs-translations/ko-KR/api/browser-window.md | 46 +++++++------- docs-translations/ko-KR/api/crash-reporter.md | 22 +++---- docs-translations/ko-KR/api/ipc-main.md | 44 +++++++------ docs-translations/ko-KR/api/ipc-renderer.md | 51 +++++++++------- docs-translations/ko-KR/api/web-contents.md | 61 ++++++++----------- docs-translations/ko-KR/api/web-view-tag.md | 8 +-- docs-translations/ko-KR/faq/electron-faq.md | 32 ++++++++++ .../desktop-environment-integration.md | 28 +++++++++ .../ko-KR/tutorial/quick-start.md | 5 +- 10 files changed, 182 insertions(+), 116 deletions(-) diff --git a/README-ko.md b/README-ko.md index 664075dd4816..b9085828d468 100644 --- a/README-ko.md +++ b/README-ko.md @@ -57,6 +57,7 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝 - [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) - [우크라이나어](https://github.com/atom/electron/tree/master/docs-translations/uk-UA) - [러시아어](https://github.com/atom/electron/tree/master/docs-translations/ru-RU) +- [프랑스어](https://github.com/atom/electron/tree/master/docs-translations/fr-FR) ## 시작하기 diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index f487a38f5da6..8bc4a1545fc4 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -451,7 +451,6 @@ var win = new BrowserWindow({ width: 800, height: 600 }); * `aspectRatio` 유지하려 하는 컨텐츠 뷰 일부의 종횡비 * `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기. - 사용 가능한 속성: * `width` Integer * `height` Integer @@ -469,7 +468,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.setBounds(options[, animate])` -* `options` Object, properties: +* `options` Object * `x` Integer * `y` Integer @@ -719,8 +718,7 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional) - 캡쳐할 페이지의 영역. - 사용할 수 있는 속성은 다음과 같습니다: +* `rect` Object (optional) - 캡쳐할 페이지의 영역 * `x` Integer * `y` Integer * `width` Integer @@ -790,34 +788,34 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` - `button` 객체의 배열 - -`button` 객체는 다음과 같은 속성을 가지고 있습니다: - -* `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. -* `tooltip` String (optional) - 버튼의 툴팁 텍스트. -* `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 - 사용됩니다. 이 속성은 다음 문자열들을 포함할 수 있습니다: - * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. - * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 - 동작에 응답하지 않는 비활성화 상태로 표시됩니다. - * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 - 종료됩니다. - * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. - * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. - * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 - 눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해 - 만들어졌습니다. -* `click` - Function +* `buttons` - Array 윈도우 작업표시줄 버튼 레이아웃의 미리보기 이미지 영역에 미리보기 툴바와 버튼 세트를 -지정합니다. 반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. +추가합니다. 반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. 미리보기 이미지 영역의 제한된 크기로 인해 미리보기 툴바에 추가될 수 있는 최대 버튼의 개수는 7개이며 이 이상 추가될 수 없습니다. 플랫폼의 제약으로 인해 미리보기 툴바는 한 번 설정되면 삭제할 수 없습니다. 하지만 이 API에 빈 배열을 전달하여 버튼들을 제거할 수 있습니다. +`buttons`는 `Button` 객체의 배열입니다: + +* `Button` 객체 + * `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. + * `tooltip` String (optional) - 버튼의 툴팁 텍스트. + * `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 + 사용됩니다. 이 속성은 다음 문자열들을 포함할 수 있습니다: + * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. + * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 + 동작에 응답하지 않는 비활성화 상태로 표시됩니다. + * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 + 종료됩니다. + * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. + * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. + * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 + 눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해 + 만들어졌습니다. + ### `win.showDefinitionForSelection()` _OS X_ 페이지의 선택된 단어에 대한 사전 검색 결과 팝업을 표시합니다. diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index 0b7daba14dd0..81713760a856 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -22,19 +22,15 @@ crashReporter.start({ ### `crashReporter.start(options)` -* `options` Object, properties: - -* `productName` String, 기본값: Electron -* `companyName` String (**필수항목**) -* `submitURL` String, (**필수항목**) - * 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다. -* `autoSubmit` Boolean, 기본값: true - * true로 지정할 경우 유저의 승인 없이 자동으로 오류를 보고합니다. -* `ignoreSystemCrashHandler` Boolean, 기본값: false -* `extra` Object - * 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다. - * 문자열로 된 속성만 정상적으로 보내집니다. - * 중첩 객체는 지원되지 않습니다. (Nested objects are not supported) +* `options` Object + * `companyName` String + * `submitURL` String - 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다. + * `productName` String (optional) - 기본값은 `Electron` 입니다. + * `autoSubmit` Boolean - 유저의 승인 없이 자동으로 오류를 보고합니다. 기본값은 + `true` 입니다. + * `ignoreSystemCrashHandler` Boolean - 기본값은 `false` 입니다. + * `extra` Object - 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다. + 문자열로 된 속성만 정상적으로 보내집니다. 중첩된 객체는 지원되지 않습니다. 다른 crashReporter API를 사용하기 전에 이 메서드를 먼저 호출해야 합니다. diff --git a/docs-translations/ko-KR/api/ipc-main.md b/docs-translations/ko-KR/api/ipc-main.md index 3ae519d294b6..30b10247f9dc 100644 --- a/docs-translations/ko-KR/api/ipc-main.md +++ b/docs-translations/ko-KR/api/ipc-main.md @@ -8,8 +8,7 @@ ## 메시지 전송 물론 메시지를 받는 것 말고도 메인 프로세스에서 랜더러 프로세스로 보내는 것도 가능합니다. -자세한 내용은 [webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-)를 -참고하세요. +자세한 내용은 [webContents.send][web-contents-send]를 참고하세요. * 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. * 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. @@ -46,34 +45,40 @@ ipcRenderer.send('asynchronous-message', 'ping'); `ipcMain`은 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -### `ipcMain.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - 이벤트 이름 -* `callback` Function +* `channel` String +* `listener` Function -이벤트가 발생하면 `event` 객체와 임의 메시지와 함께 `callback`이 호출됩니다. +`channel`에 대해 이벤트를 리스닝합니다. 새로운 메시지가 도착하면 `listener`가 +`listener(event, args...)` 형식으로 호출됩니다. -### `ipcMain.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - 이벤트의 이름 -* `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 +* `channel` String +* `listener` Function + +이벤트에 대해 한 번만 작동하는 `listener` 함수를 등록합니다. 이 `listener`는 등록된 +후 `channel`에 보내지는 메시지에 한해 호출됩니다. 호출된 이후엔 리스너가 삭제됩니다. + +### `ipcMain.removeListener(channel, listener)` + +* `channel` String +* `listener` Function 메시지 수신을 완료한 후, 더 이상의 콜백이 필요하지 않을 때 또는 몇 가지 이유로 채널의 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. +지정한 `channel`에 대한 리스너를 저장하는 배열에서 지정한 `listener`를 삭제합니다. + ### `ipcMain.removeAllListeners(channel)` -* `channel` String - 이벤트의 이름 +* `channel` String (optional) -이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. +이 ipc 채널에 등록된 모든 핸들러들을 삭제하거나 지정한 `channel`을 삭제합니다. -### `ipcMain.once(channel, callback)` - -`ipcMain.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. -`callback`이 한 번 호출된 이후 활성화되지 않습니다. - -## IPC Event +## Event 객체 `callback`에서 전달된 `event` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: @@ -85,5 +90,6 @@ ipcRenderer.send('asynchronous-message', 'ping'); 메시지를 보낸 `webContents` 객체를 반환합니다. `event.sender.send` 메서드를 통해 비동기로 메시지를 전달할 수 있습니다. 자세한 내용은 -[webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-)를 -참고하세요. +[webContents.send][web-contents-send]를 참고하세요. + +[web-contents-send]: web-contents.md#webcontentssendchannel-arg1-arg2- diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index 12fac95bbeeb..0d43b157d165 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -10,32 +10,38 @@ `ipcRenderer`는 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -### `ipcRenderer.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - 이벤트 이름 -* `callback` Function +* `channel` String +* `listener` Function -이벤트가 일어나면 `event` 객체와 임의의 인자와 함께 `callback` 함수가 호출됩니다. +`channel`에 대해 이벤트를 리스닝합니다. 새로운 메시지가 도착하면 `listener`가 +`listener(event, args...)` 형식으로 호출됩니다. -### `ipcRenderer.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - 이벤트의 이름 -* `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 +* `channel` String +* `listener` Function + +이벤트에 대해 한 번만 작동하는 `listener` 함수를 등록합니다. 이 `listener`는 등록된 +후 `channel`에 보내지는 메시지에 한해 호출됩니다. 호출된 이후엔 리스너가 삭제됩니다. + +### `ipcMain.removeListener(channel, listener)` + +* `channel` String +* `listener` Function 메시지 수신을 완료한 후, 더 이상의 콜백이 필요하지 않을 때 또는 몇 가지 이유로 채널의 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. -### `ipcRenderer.removeAllListeners(channel)` +지정한 `channel`에 대한 리스너를 저장하는 배열에서 지정한 `listener`를 삭제합니다. -* `channel` String - 이벤트의 이름 +### `ipcMain.removeAllListeners(channel)` -이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. +* `channel` String (optional) -### `ipcRenderer.once(channel, callback)` - -`ipcRenderer.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. -`callback`이 한 번 호출된 이후 활성화되지 않습니다. +이 ipc 채널에 등록된 모든 핸들러들을 삭제하거나 지정한 `channel`을 삭제합니다. ## 메시지 보내기 @@ -43,23 +49,26 @@ ### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 -인자를 사용할 수도 있습니다. 메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 +인수를 사용할 수도 있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 +프로토타입 체인은 포함되지 않게 됩니다. + +메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 이벤트를 리스닝 할 수 있습니다. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 -인자를 사용할 수도 있습니다. 메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 -할 수 있습니다. +인자를 사용할 수도 있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 +프로토타입 체인은 포함되지 않게 됩니다. -메인 프로세스에선 `ipcMain` 모듈의 `channel` 이벤트를 통해 받은 +메인 프로세스는 `ipcMain` 모듈을 통해 `channel` 이벤트를 리스닝 할 수 있고, `event.returnValue`로 회신 할 수 있습니다. __참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 사용 목적이 @@ -67,7 +76,7 @@ __참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일 ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `ipcRenderer.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 3f9a7daaaa76..6e41f31155ce 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -255,8 +255,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. - * `matches` Integer (Optional) - 일치하는 개수. - * `selectionArea` Object (Optional) - 첫 일치 부위의 좌표. + * `matches` Integer (optional) - 일치하는 개수. + * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) 요청의 결과를 사용할 수 있을 때 발생하는 이벤트입니다. @@ -307,7 +307,7 @@ Returns: ### `webContents.loadURL(url[, options])` * `url` URL -* `options` Object (optional), 속성들: +* `options` Object (optional) * `httpReferrer` String - HTTP 레퍼러 url. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. @@ -493,7 +493,7 @@ CSS 코드를 현재 웹 페이지에 삽입합니다. ### `webContents.findInPage(text[, options])` * `text` String - 찾을 컨텐츠, 반드시 공백이 아니여야 합니다. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - 앞에서부터 검색할지 뒤에서부터 검색할지 여부입니다. 기본값은 `true`입니다. * `findNext` Boolean - 작업을 계속 처리할지 첫 요청만 처리할지 여부입니다. 기본값은 @@ -546,11 +546,10 @@ ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족 ### `webContents.print([options])` -`options` Object (optional), properties: - -* `silent` Boolean - 사용자에게 프린트 설정을 묻지 않습니다. 기본값을 `false`입니다. -* `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 - `false`입니다. +`options` Object (optional) + * `silent` Boolean - 사용자에게 프린트 설정을 묻지 않습니다. 기본값을 `false`입니다. + * `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 + `false`입니다. 윈도우의 웹 페이지를 프린트합니다. `silent`가 `false`로 지정되어있을 땐, Electron이 시스템의 기본 프린터와 기본 프린터 설정을 가져옵니다. @@ -565,32 +564,23 @@ print기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이 ### `webContents.printToPDF(options, callback)` -`options` Object, properties: - -* `marginsType` Integer - 사용할 마진의 종류를 지정합니다. - * 0 - default - * 1 - none - * 2 - minimum -* `pageSize` String - 생성되는 PDF의 페이지 크기를 지정합니다. - * `A5` - * `A4` - * `A3` - * `Legal` - * `Letter` - * `Tabloid` -* `printBackground` Boolean - CSS 배경을 프린트할지 여부를 정합니다. -* `printSelectionOnly` Boolean - 선택된 영역만 프린트할지 여부를 정합니다. -* `landscape` Boolean - landscape을 위해선 `true`를, portrait를 위해선 `false`를 - 사용합니다. - -`callback` Function - `function(error, data) {}` - -* `error` Error -* `data` Buffer - PDF 파일 내용. +* `options` Object + * `marginsType` Integer - 사용할 마진의 종류를 지정합니다. 0 부터 2 사이 값을 사용할 + 수 있고 각각 기본 마진, 마진 없음, 최소 마진입니다. + * `pageSize` String - 생성되는 PDF의 페이지 크기를 지정합니다. 값은 `A3`, `A4`, + `A5`, `Legal`, `Letter` 와 `Tabloid`가 사용될 수 있습니다. + * `printBackground` Boolean - CSS 배경을 프린트할지 여부를 정합니다. + * `printSelectionOnly` Boolean - 선택된 영역만 프린트할지 여부를 정합니다. + * `landscape` Boolean - landscape을 위해선 `true`를, portrait를 위해선 `false`를 + 사용합니다. +* `callback` Function - `function(error, data) {}` Chromium의 미리보기 프린팅 커스텀 설정을 이용하여 윈도우의 웹 페이지를 PDF로 프린트합니다. +`callback`은 작업이 완료되면 `callback(error, data)` 형식으로 호출됩니다. `data`는 +생성된 PDF 데이터를 담고있는 `Buffer`입니다. + 기본으로 비어있는 `options`은 다음과 같이 여겨지게 됩니다: ```javascript @@ -643,7 +633,7 @@ mainWindow.webContents.on('devtools-opened', function() { ### `webContents.openDevTools([options])` -* `options` Object (optional). Properties: +* `options` Object (optional) * `detach` Boolean - 새 창에서 개발자 도구를 엽니다. 개발자 도구를 엽니다. @@ -681,8 +671,11 @@ mainWindow.webContents.on('devtools-opened', function() { * `arg` (optional) `channel`을 통하여 렌더러 프로세스에 비동기 메시지를 보냅니다. 임의의 인수를 보낼수도 -있습니다. 렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리슨하여 메시지를 -처리할 수 있습니다. +있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 프로토타입 체인은 +포함되지 않게 됩니다. + +렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리스닝하여 메시지를 처리할 +수 있습니다. 메인 프로세스에서 렌더러 프로세스로 메시지를 보내는 예시 입니다: diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index bd07c883e061..30da9f253b45 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -178,7 +178,7 @@ webview.addEventListener("dom-ready", function() { ### `.loadURL(url[, options])` * `url` URL -* `options` Object (optional), 속성들: +* `options` Object (optional) * `httpReferrer` String - HTTP 레퍼러 url. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. @@ -370,7 +370,7 @@ Service worker에 대한 개발자 도구를 엽니다. ### `webContents.findInPage(text[, options])` * `text` String - 찾을 컨텐츠, 반드시 공백이 아니여야 합니다. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - 앞에서부터 검색할지 뒤에서부터 검색할지 여부입니다. 기본값은 `true`입니다. * `findNext` Boolean - 작업을 계속 처리할지 첫 요청만 처리할지 여부입니다. 기본값은 @@ -557,8 +557,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. - * `matches` Integer (Optional) - 일치하는 개수. - * `selectionArea` Object (Optional) - 첫 일치 부위의 좌표. + * `matches` Integer (optional) - 일치하는 개수. + * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) 요청의 결과를 사용할 수 있을 때 발생하는 이벤트입니다. diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index 0978dc00539b..ea9953fcd4cd 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -18,6 +18,34 @@ Node.js의 새로운 기능은 보통 V8 업그레이드에서 가져옵니다. 브라우저에 탑재된 V8을 사용하고 있습니다. 눈부신 새로운 Node.js 버전의 자바스크립트 기능은 보통 이미 Electron에 있습니다. +## 어떻게 웹 페이지 간에 데이터를 공유할 수 있나요? + +두 웹페이지 간에 (랜더러 프로세스) 데이터를 공유하려면 간단히 이미 모든 브라우저에서 +사용할 수 있는 HTML5 API들을 사용하면 됩니다. 가장 좋은 후보는 +[Storage API][storage], [`localStorage`][local-storage], +[`sessionStorage`][session-storage], 그리고 [IndexedDB][indexed-db]가 있습니다. + +또는 Electron에서만 사용할 수 있는 IPC 시스템을 사용하여 메인 프로세스의 global +변수에 데이터를 저장한 후 다음과 같이 랜더러 프로세스에서 `remote` 모듈을 사용하여 +접근할 수 있습니다: + +```javascript +// 메인 프로세스에서 +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// 첫 번째 페이지에서 +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// 두 번째 페이지에서 +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + ## 제작한 어플리케이션의 윈도우/트레이가 몇 분 후에나 나타납니다. 이러한 문제가 발생하는 이유는 보통 윈도우/트레이를 담은 변수에 가비지 컬렉션이 작동해서 @@ -119,3 +147,7 @@ npm uninstall -g electron [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index cd6ff545e14d..38830b91e82d 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -263,6 +263,33 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## 작업 표시줄의 아이콘 오버레이 (Windows) + +Windows에선 작업 표시줄 버튼에 어플리케이션의 상태를 표시하는 작은 오버레이를 사용할 +수 있습니다. MSDN에서 인용하자면 (영문): + +> Icon overlays serve as a contextual notification of status, and are intended +> to negate the need for a separate notification area status icon to communicate +> that information to the user. For instance, the new mail status in Microsoft +> Outlook, currently shown in the notification area, can now be indicated +> through an overlay on the taskbar button. Again, you must decide during your +> development cycle which method is best for your application. Overlay icons are +> intended to supply important, long-standing status or notifications such as +> network status, messenger status, or new mail. The user should not be +> presented with constantly changing overlays or animations. + +__작업 표시줄 버튼 위의 오버레이:__ + +![작업 표시줄 버튼 위의 오버레이](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +윈도우에 오버레이 아이콘을 설정하려면 [BrowserWindow.setOverlayIcon][setoverlayicon] +API를 사용할 수 있습니다: + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## 대표 파일 제시 (OS X) OS X는 창에서 대표 파일을 설정할 수 있습니다. 타이틀바에서 파일 아이콘이 있고, 사용자가 @@ -287,6 +314,7 @@ window.setDocumentEdited(true); [clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows [setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows [setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 [setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x [setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 708a48080ff4..82d359e0de5f 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -12,7 +12,7 @@ Electron은 웹 페이지의 GUI를 사용합니다. 쉽게 말해 Electron은 ### 메인 프로세스 -Electron은 실행될 때 __메인 프로세스__로 불리는 `package.json`의 `main` 스크립트를 +Electron은 실행될 때 __메인 프로세스__ 로 불리는 `package.json`의 `main` 스크립트를 호출합니다. 이 스크립트는 메인 프로세스에서 작동합니다. GUI 컴포넌트를 조작하거나 웹 페이지 창을 생성할 수 있습니다. @@ -43,6 +43,7 @@ API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 Electron에는 메인 프로세스와 랜더러 프로세스 사이에 통신을 할 수 있도록 [ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. 또는 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. +또한 FAQ에서 [다양한 객체를 공유하는 방법](share-data)도 소개하고 있습니다. ## 첫번째 Electron 앱 만들기 @@ -211,3 +212,5 @@ $ cd electron-quick-start # 어플리케이션의 종속성 모듈을 설치한 후 실행합니다 $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#어떻게-웹-페이지-간에-데이터를-공유할-수-있나요 From ee0cac7d5475549802fadcf0ab67a9a24354eef4 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Tue, 16 Feb 2016 21:23:13 -0500 Subject: [PATCH 057/132] Remove command line switches, add v8 flags --- atom/browser/lib/init.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index b687aa6eedad..4769faee0a39 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const util = require('util'); const Module = require('module'); +const v8 = require('v8'); var slice = [].slice; @@ -129,22 +130,14 @@ if (packageJson.desktopName != null) { app.setDesktopName((app.getName()) + ".desktop"); } +// Set v8 flags +if (packageJson.v8Flags != null) { + v8.setFlagsFromString(packageJson.v8Flags); +} + // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); -// Add other command line switches -if (packageJson.commandLineSwitches) { - for (let i = 0; i < packageJson.commandLineSwitches.length; i++) { - const option = packageJson.commandLineSwitches[i]; - - if (typeof option === 'string') { - app.commandLine.appendSwitch(option); - } else { - app.commandLine.appendSwitch(option[0], option[1]); - } - } -} - // Set the user path according to application's name. app.setPath('userData', path.join(app.getPath('appData'), app.getName())); From baf44c7a4144c3c78a9bcf01708f5a580fbcd889 Mon Sep 17 00:00:00 2001 From: deenjun Date: Wed, 17 Feb 2016 10:42:59 +0800 Subject: [PATCH 058/132] tanslate file-object.md --- docs-translations/zh-CN/api/file-object.md | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs-translations/zh-CN/api/file-object.md diff --git a/docs-translations/zh-CN/api/file-object.md b/docs-translations/zh-CN/api/file-object.md new file mode 100644 index 000000000000..343fc4dc53ae --- /dev/null +++ b/docs-translations/zh-CN/api/file-object.md @@ -0,0 +1,33 @@ +# `文件`对象 + +为了让用户能够通过HTML5的file API直接操作本地文件,DOM的File接口提供了对本地文件的抽象。Electron在File接口中增加了一个path属性,它是文件在系统中的真实路径。 + +The DOM’s File interface provides abstraction around native files in order to let users work on native files directly with the HTML5 file API. Electron has added a path attribute to the File interface which exposes the file’s real path on filesystem. + +--- + +获取拖动到APP中文件的真实路径的例子: + +Example on getting a real path from a dragged-onto-the-app file: + +``` +
+ Drag your file here +
+ + +``` From 01ede11cb885cc0f77fd23258f37aaaf92c30652 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 10:54:44 +0800 Subject: [PATCH 059/132] Skip eslint on our Windows build machine for now --- script/eslint.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/script/eslint.py b/script/eslint.py index 8fa2c3a7e3a7..7b912e0e1d6c 100755 --- a/script/eslint.py +++ b/script/eslint.py @@ -4,6 +4,7 @@ import glob import os import sys +from lib.config import PLATFORM from lib.util import execute @@ -13,6 +14,10 @@ SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) def main(): os.chdir(SOURCE_ROOT) + # Skip eslint on our Windows build machine for now. + if PLATFORM == 'win32' and os.getenv('JANKY_SHA1'): + return + eslint = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'eslint') if sys.platform in ['win32', 'cygwin']: eslint += '.cmd' From 28635e5f2c20f2d8642965460e9e5eb378cd32df Mon Sep 17 00:00:00 2001 From: deenjun Date: Wed, 17 Feb 2016 14:54:57 +0800 Subject: [PATCH 060/132] remove original English text --- docs-translations/zh-CN/api/file-object.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs-translations/zh-CN/api/file-object.md b/docs-translations/zh-CN/api/file-object.md index 343fc4dc53ae..ef320b36994e 100644 --- a/docs-translations/zh-CN/api/file-object.md +++ b/docs-translations/zh-CN/api/file-object.md @@ -1,15 +1,11 @@ -# `文件`对象 +# `File`对象 为了让用户能够通过HTML5的file API直接操作本地文件,DOM的File接口提供了对本地文件的抽象。Electron在File接口中增加了一个path属性,它是文件在系统中的真实路径。 -The DOM’s File interface provides abstraction around native files in order to let users work on native files directly with the HTML5 file API. Electron has added a path attribute to the File interface which exposes the file’s real path on filesystem. - --- 获取拖动到APP中文件的真实路径的例子: -Example on getting a real path from a dragged-onto-the-app file: - ```
Drag your file here From 7fece7e9b3ecfa57b5a37e07c2f4eb65169589dd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 22:21:14 +0800 Subject: [PATCH 061/132] Link with ffmpeg --- atom.gyp | 3 +++ vendor/brightray | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index dbaf6db56298..c8c714858b43 100644 --- a/atom.gyp +++ b/atom.gyp @@ -144,6 +144,7 @@ }, { 'copied_libraries': [ '<(libchromiumcontent_dir)/pdf.dll', + '<(libchromiumcontent_dir)/ffmpeg.dll', ], }], ], @@ -193,6 +194,7 @@ }, { 'copied_libraries': [ '<(PRODUCT_DIR)/lib/libnode.so', + '<(libchromiumcontent_dir)/libffmpeg.so', ], }], ], @@ -461,6 +463,7 @@ }, { 'copied_libraries': [ '<(PRODUCT_DIR)/libnode.dylib', + '<(libchromiumcontent_dir)/libffmpeg.dylib', ], }], ], diff --git a/vendor/brightray b/vendor/brightray index 2a5cd7178b64..d06de26dff8b 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 2a5cd7178b641de91ca6eb0bca826fea588f923a +Subproject commit d06de26dff8b641d9aee4c78ee830b416710f554 From 3d3fc18a3ab8aa409296b41ed00c8474911ad254 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 22:21:59 +0800 Subject: [PATCH 062/132] Update libchromiumcontent to use shared ffmpeg --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 279fa7340a96..004e87dd0700 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'ad63d8ba890bcaad2f1b7e6de148b7992f4d3af7' +LIBCHROMIUMCONTENT_COMMIT = '1be1a55abba527d6fb0fc2a589cbaef2f5a6a79e' PLATFORM = { 'cygwin': 'win32', From d8679b38993ae66c9e6d60968da19124005d09b6 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 2 Feb 2016 23:01:00 -0800 Subject: [PATCH 063/132] Allow openExternal to open URLs in the background #3224 --- .../atom_resource_dispatcher_host_delegate.cc | 2 +- atom/common/api/atom_api_shell.cc | 12 +++++++++++- atom/common/platform_util.h | 2 +- atom/common/platform_util_linux.cc | 2 +- atom/common/platform_util_mac.mm | 12 ++++++++++-- atom/common/platform_util_win.cc | 2 +- docs/api/shell.md | 10 ++++++++-- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index aaba1f31045b..33e90671aba8 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -26,7 +26,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool has_user_gesture) { GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url)); + base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); return true; } diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index a4599ee0c359..d479911fbe32 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,12 +12,22 @@ namespace { +bool OpenExternal(const GURL& url, mate::Arguments* args) { + bool without_activation = false; + if (args->Length() == 2) { + mate::Dictionary options; + args->GetNext(&options); + options.Get("withoutActivation", &without_activation); + } + return platform_util::OpenExternal(url, without_activation); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("openExternal", &platform_util::OpenExternal); + dict.SetMethod("openExternal", &OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 312942c4f5dc..3550c243bb68 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -23,7 +23,7 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url); +bool OpenExternal(const GURL& url, const bool without_activation); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index aa7439968daa..fd4dcba6973b 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -64,7 +64,7 @@ void OpenItem(const base::FilePath& full_path) { XDGOpen(full_path.value()); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { if (url.SchemeIs("mailto")) return XDGEmail(url.spec()); else diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index 7184593ae190..e84b3fbec307 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -119,7 +119,7 @@ void OpenItem(const base::FilePath& full_path) { } } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { DCHECK([NSThread isMainThread]); NSURL* ns_url = net::NSURLWithGURL(url); if (!ns_url) { @@ -136,7 +136,15 @@ bool OpenExternal(const GURL& url) { } CFRelease(openingApp); // NOT A BUG; LSGetApplicationForURL retains for us - return [[NSWorkspace sharedWorkspace] openURL:ns_url]; + NSUInteger launchOptions = NSWorkspaceLaunchDefault; + if (without_activation) + launchOptions = launchOptions | NSWorkspaceLaunchWithoutActivation; + + return [[NSWorkspace sharedWorkspace] openURLs: @[ns_url] + withAppBundleIdentifier: nil + options: launchOptions + additionalEventParamDescriptor: NULL + launchIdentifiers: NULL]; } bool MoveItemToTrash(const base::FilePath& full_path) { diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 4de5224668b6..76b71cb7f702 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -301,7 +301,7 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. diff --git a/docs/api/shell.md b/docs/api/shell.md index e6678a955364..a7f03a52f9c7 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -26,12 +26,18 @@ Show the given file in a file manager. If possible, select the file. Open the given file in the desktop's default manner. -### `shell.openExternal(url)` +### `shell.openExternal(url[, options])` * `url` String Open the given external protocol URL in the desktop's default manner. (For -example, mailto: URLs in the user's default mail agent.) +example, mailto: URLs in the user's default mail agent.) Returns true if an +application was available to open the URL, false otherwise. + +On Mac OS X, you can pass additional options to openExternal: + +- withoutActivation: Pass true to open the URL without bringing the + application into the foreground. ### `shell.moveItemToTrash(fullPath)` From 52db43eee55975ab1cbd4926beedbd4b037c2a38 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Wed, 3 Feb 2016 11:35:01 -0800 Subject: [PATCH 064/132] Fix linter error --- atom/browser/atom_resource_dispatcher_host_delegate.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 33e90671aba8..0ed59b71be98 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -26,7 +26,8 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool has_user_gesture) { GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); + base::Bind( + base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); return true; } From f5bed87199732cfac34b4dfe5ddcc6072fd5b549 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 15:55:37 -0800 Subject: [PATCH 065/132] without_activation -> activate --- atom/common/api/atom_api_shell.cc | 12 +----------- atom/common/api/lib/shell.js | 18 +++++++++++++++++- atom/common/platform_util.h | 2 +- atom/common/platform_util_linux.cc | 2 +- atom/common/platform_util_mac.mm | 6 +++--- atom/common/platform_util_win.cc | 2 +- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index d479911fbe32..d0e795e87455 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,22 +12,12 @@ namespace { -bool OpenExternal(const GURL& url, mate::Arguments* args) { - bool without_activation = false; - if (args->Length() == 2) { - mate::Dictionary options; - args->GetNext(&options); - options.Get("withoutActivation", &without_activation); - } - return platform_util::OpenExternal(url, without_activation); -} - void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("openExternal", &OpenExternal); + dict.SetMethod("_openExternal", &platform_util::OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index 08cc4e8eb41c..e032a7370762 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -1 +1,17 @@ -module.exports = process.atomBinding('shell'); +'use strict'; + +const bindings = process.atomBinding('shell'); + +exports.beep = bindings.beep; +exports.moveItemToTrash = bindings.moveItemToTrash; +exports.openItem = bindings.openItem; +exports.showItemInFolder = bindings.showItemInFolder; + +exports.openExternal = (url, options) => { + var activate = true; + if (options != null && options.activate != null) { + activate = !!options.activate; + } + + bindings._openExternal(url, activate); +} diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 3550c243bb68..4565221e9d84 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -23,7 +23,7 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url, const bool without_activation); +bool OpenExternal(const GURL& url, bool activate); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index fd4dcba6973b..1e437b866cc0 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -64,7 +64,7 @@ void OpenItem(const base::FilePath& full_path) { XDGOpen(full_path.value()); } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { if (url.SchemeIs("mailto")) return XDGEmail(url.spec()); else diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index e84b3fbec307..98bc4e537d89 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -119,7 +119,7 @@ void OpenItem(const base::FilePath& full_path) { } } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { DCHECK([NSThread isMainThread]); NSURL* ns_url = net::NSURLWithGURL(url); if (!ns_url) { @@ -137,8 +137,8 @@ bool OpenExternal(const GURL& url, const bool without_activation) { CFRelease(openingApp); // NOT A BUG; LSGetApplicationForURL retains for us NSUInteger launchOptions = NSWorkspaceLaunchDefault; - if (without_activation) - launchOptions = launchOptions | NSWorkspaceLaunchWithoutActivation; + if (!activate) + launchOptions |= NSWorkspaceLaunchWithoutActivation; return [[NSWorkspace sharedWorkspace] openURLs: @[ns_url] withAppBundleIdentifier: nil diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 76b71cb7f702..12591a94d569 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -301,7 +301,7 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. From 42041cd40273851d694bff1da6abd67489cb53e9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 15:58:33 -0800 Subject: [PATCH 066/132] Use markdown list for new options param --- docs/api/shell.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/api/shell.md b/docs/api/shell.md index a7f03a52f9c7..823dc481bb07 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -29,16 +29,14 @@ Open the given file in the desktop's default manner. ### `shell.openExternal(url[, options])` * `url` String +* `options` Object (optional) _OS X_ + * `activate` Boolean - `true` to bring the opened application to the + foreground. The default is `true`. Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent.) Returns true if an application was available to open the URL, false otherwise. -On Mac OS X, you can pass additional options to openExternal: - -- withoutActivation: Pass true to open the URL without bringing the - application into the foreground. - ### `shell.moveItemToTrash(fullPath)` * `fullPath` String From 5e5313d8b1659f9fbdee5ff3cf6198c696928005 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:02:41 -0800 Subject: [PATCH 067/132] Return value from bindings method --- atom/common/api/lib/shell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index e032a7370762..7caf8518395d 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -13,5 +13,5 @@ exports.openExternal = (url, options) => { activate = !!options.activate; } - bindings._openExternal(url, activate); + return bindings._openExternal(url, activate); } From 04517caf36265055505c6dbec085c34aa0e14b33 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:08:36 -0800 Subject: [PATCH 068/132] Add missing semicolon --- atom/common/api/lib/shell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index 7caf8518395d..d62280277c53 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -14,4 +14,4 @@ exports.openExternal = (url, options) => { } return bindings._openExternal(url, activate); -} +}; From 3f42909ecfe46fc786cb7e9eb662bb7f6e255154 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:09:30 -0800 Subject: [PATCH 069/132] Call OpenExternal with new true default to activate arg --- atom/browser/atom_resource_dispatcher_host_delegate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 0ed59b71be98..4d969786c19a 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -27,7 +27,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( - base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); + base::IgnoreResult(platform_util::OpenExternal), escaped_url, true)); return true; } From b3ac48cf52f0b36831fb8366fc16ecf2be287cf8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:05:21 -0800 Subject: [PATCH 070/132] Handle argument parsing in C++ --- atom/common/api/atom_api_shell.cc | 13 ++++++++++++- atom/common/api/lib/shell.js | 18 +----------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index d0e795e87455..f99e2ba1854e 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,12 +12,23 @@ namespace { +bool OpenExternal(const GURL& url, mate::Arguments* args) { + bool activate = true; + if (args->Length() == 2) { + mate::Dictionary options; + if (args->GetNext(&options)) { + options.Get("activate", &activate); + } + } + return platform_util::OpenExternal(url, activate); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("_openExternal", &platform_util::OpenExternal); + dict.SetMethod("openExternal", &OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index d62280277c53..08cc4e8eb41c 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -1,17 +1 @@ -'use strict'; - -const bindings = process.atomBinding('shell'); - -exports.beep = bindings.beep; -exports.moveItemToTrash = bindings.moveItemToTrash; -exports.openItem = bindings.openItem; -exports.showItemInFolder = bindings.showItemInFolder; - -exports.openExternal = (url, options) => { - var activate = true; - if (options != null && options.activate != null) { - activate = !!options.activate; - } - - return bindings._openExternal(url, activate); -}; +module.exports = process.atomBinding('shell'); From 709661156a0d9bb4b96bbcb98687912af6f6aa83 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:46:49 -0800 Subject: [PATCH 071/132] Use const for requires --- spec/api-app-spec.js | 16 ++++++---------- spec/api-clipboard-spec.js | 10 ++++------ spec/api-crash-reporter-spec.js | 27 +++++++++++---------------- spec/api-debugger-spec.js | 12 +++--------- spec/api-ipc-spec.js | 15 +++++++-------- spec/api-menu-spec.js | 10 +++++----- spec/api-screen-spec.js | 7 ++----- spec/api-web-frame-spec.js | 10 +++------- 8 files changed, 41 insertions(+), 66 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 0019ec59d5f0..176a94a0437d 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -1,14 +1,10 @@ -var BrowserWindow, ChildProcess, app, assert, path, ref, remote; +const assert = require('assert'); +const ChildProcess = require('child_process'); +const path = require('path'); +const remote = require('electron').remote; -assert = require('assert'); - -ChildProcess = require('child_process'); - -path = require('path'); - -remote = require('electron').remote; - -ref = remote.require('electron'), app = ref.app, BrowserWindow = ref.BrowserWindow; +const app = remote.require('electron').app; +const BrowserWindow = remote.require('electron').BrowserWindow; describe('electron module', function() { it ('can prevent exposing internal modules to require', function(done) { diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index fe94e330d414..48ba558dfd0f 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -1,10 +1,8 @@ -var assert, clipboard, nativeImage, path, ref; +const assert = require('assert'); +const path = require('path'); -assert = require('assert'); - -path = require('path'); - -ref = require('electron'), clipboard = ref.clipboard, nativeImage = ref.nativeImage; +const clipboard = require('electron').clipboard; +const nativeImage = require('electron').nativeImage; describe('clipboard module', function() { var fixtures; diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index b3c4c3115896..dac1307a8e8f 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -1,18 +1,13 @@ -var BrowserWindow, app, assert, crashReporter, http, multiparty, path, ref, remote, url; +const assert = require('assert'); +const http = require('http'); +const multiparty = require('multiparty'); +const path = require('path'); +const url = require('url'); -assert = require('assert'); - -path = require('path'); - -http = require('http'); - -url = require('url'); - -multiparty = require('multiparty'); - -remote = require('electron').remote; - -ref = remote.require('electron'), app = ref.app, crashReporter = ref.crashReporter, BrowserWindow = ref.BrowserWindow; +const remote = require('electron').remote; +const app = remote.require('electron').app; +const crashReporter = remote.require('electron').crashReporter; +const BrowserWindow = remote.require('electron').BrowserWindow; describe('crash-reporter module', function() { var fixtures, isCI, w; @@ -63,7 +58,7 @@ describe('crash-reporter module', function() { return server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; - url = url.format({ + const crashUrl = url.format({ protocol: 'file', pathname: path.join(fixtures, 'api', 'crash.html'), search: "?port=" + port @@ -74,7 +69,7 @@ describe('crash-reporter module', function() { submitURL: "http://127.0.0.1:" + port }); } - return w.loadURL(url); + return w.loadURL(crashUrl); }); }); return describe(".start(options)", function() { diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 7a16ca7263c0..3c69d38ed327 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -1,12 +1,6 @@ -var assert, path, remote, BrowserWindow; - -assert = require('assert'); - -path = require('path'); - -remote = require('electron').remote; - -BrowserWindow = remote.BrowserWindow; +const assert = require('assert'); +const path = require('path'); +const BrowserWindow = require('electron').remote.BrowserWindow; describe('debugger module', function() { var fixtures, w; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 66f392a577c9..ce5641b71cb3 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -1,14 +1,13 @@ -var BrowserWindow, assert, comparePaths, ipcMain, ipcRenderer, path, ref, ref1, remote; +const assert = require('assert'); +const path = require('path'); -assert = require('assert'); +const ipcRenderer = require('electron').ipcRenderer; +const remote = require('electron').remote; -path = require('path'); +const ipcMain = remote.require('electron').ipcMain; +const BrowserWindow = remote.require('electron').BrowserWindow; -ref = require('electron'), ipcRenderer = ref.ipcRenderer, remote = ref.remote; - -ref1 = remote.require('electron'), ipcMain = ref1.ipcMain, BrowserWindow = ref1.BrowserWindow; - -comparePaths = function(path1, path2) { +const comparePaths = function(path1, path2) { if (process.platform === 'win32') { path1 = path1.toLowerCase(); path2 = path2.toLowerCase(); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 5771358337e4..67705d22b3d4 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -1,10 +1,10 @@ -var Menu, MenuItem, assert, ipcRenderer, ref, ref1, remote; +const assert = require('assert'); -assert = require('assert'); +const remote = require('electron').remote; +const ipcRenderer = require('electron').ipcRenderer; -ref = require('electron'), remote = ref.remote, ipcRenderer = ref.ipcRenderer; - -ref1 = remote.require('electron'), Menu = ref1.Menu, MenuItem = ref1.MenuItem; +const Menu = remote.require('electron').Menu; +const MenuItem = remote.require('electron').MenuItem; describe('menu module', function() { describe('Menu.buildFromTemplate', function() { diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index b393d4b99ee8..abc127841651 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -1,8 +1,5 @@ -var assert, screen; - -assert = require('assert'); - -screen = require('electron').screen; +const assert = require('assert'); +const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 3d287a6acba9..d3d43986ec8b 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -1,10 +1,6 @@ -var assert, path, webFrame; - -assert = require('assert'); - -path = require('path'); - -webFrame = require('electron').webFrame; +const assert = require('assert'); +const path = require('path'); +const webFrame = require('electron').webFrame; describe('webFrame module', function() { var fixtures; From e63c3c727a2d42a266b3a020d882a9b0c3a0bf83 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:09:41 -0800 Subject: [PATCH 072/132] Add newlines between describe/it blocks --- spec/api-app-spec.js | 18 ++- spec/api-clipboard-spec.js | 8 +- spec/api-crash-reporter-spec.js | 21 ++- spec/api-debugger-spec.js | 7 +- spec/api-ipc-spec.js | 63 ++++---- spec/api-menu-spec.js | 48 +++--- spec/api-protocol-spec.js | 160 ++++++++++--------- spec/api-screen-spec.js | 7 +- spec/api-session-spec.js | 16 +- spec/api-web-frame-spec.js | 6 +- spec/api-web-request-spec.js | 36 ++++- spec/asar-spec.js | 271 ++++++++++++++++++-------------- spec/chromium-spec.js | 59 +++++-- spec/modules-spec.js | 7 +- spec/node-spec.js | 23 ++- 15 files changed, 455 insertions(+), 295 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 176a94a0437d..ea305ae9535d 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -27,6 +27,7 @@ describe('app module', function() { return assert.equal(app.getVersion(), '0.1.0'); }); }); + describe('app.setVersion(version)', function() { return it('overrides the version', function() { assert.equal(app.getVersion(), '0.1.0'); @@ -35,11 +36,13 @@ describe('app module', function() { return app.setVersion('0.1.0'); }); }); + describe('app.getName()', function() { return it('returns the name field of package.json', function() { return assert.equal(app.getName(), 'Electron Test'); }); }); + describe('app.setName(name)', function() { return it('overrides the name', function() { assert.equal(app.getName(), 'Electron Test'); @@ -48,17 +51,20 @@ describe('app module', function() { return app.setName('Electron Test'); }); }); + describe('app.getLocale()', function() { return it('should not be empty', function() { return assert.notEqual(app.getLocale(), ''); }); }); + describe('app.exit(exitCode)', function() { - var appProcess; - appProcess = null; + var appProcess = null; + afterEach(function() { return appProcess != null ? appProcess.kill() : void 0; }); + return it('emits a process exit event with the code', function(done) { var appPath, electronPath, output; appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); @@ -77,15 +83,17 @@ describe('app module', function() { }); }); }); + return describe('BrowserWindow events', function() { - var w; - w = null; + var w = null; + afterEach(function() { if (w != null) { w.destroy(); } return w = null; }); + it('should emit browser-window-focus event when window is focused', function(done) { app.once('browser-window-focus', function(e, window) { assert.equal(w.id, window.id); @@ -96,6 +104,7 @@ describe('app module', function() { }); return w.emit('focus'); }); + it('should emit browser-window-blur event when window is blured', function(done) { app.once('browser-window-blur', function(e, window) { assert.equal(w.id, window.id); @@ -106,6 +115,7 @@ describe('app module', function() { }); return w.emit('blur'); }); + return it('should emit browser-window-created event when window is created', function(done) { app.once('browser-window-created', function(e, window) { return setImmediate(function() { diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 48ba558dfd0f..28afb4a5307d 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -5,8 +5,8 @@ const clipboard = require('electron').clipboard; const nativeImage = require('electron').nativeImage; describe('clipboard module', function() { - var fixtures; - fixtures = path.resolve(__dirname, 'fixtures'); + var fixtures = path.resolve(__dirname, 'fixtures'); + describe('clipboard.readImage()', function() { return it('returns NativeImage intance', function() { var i, p; @@ -16,6 +16,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); + describe('clipboard.readText()', function() { return it('returns unicode string correctly', function() { var text; @@ -24,6 +25,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readText(), text); }); }); + describe('clipboard.readHtml()', function() { return it('returns markup correctly', function() { var markup, text; @@ -33,6 +35,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readHtml(), markup); }); }); + describe('clipboard.readRtf', function() { return it('returns rtf text correctly', function() { var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; @@ -40,6 +43,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readRtf(), rtf); }); }); + return describe('clipboard.write()', function() { return it('returns data correctly', function() { var i, markup, p, text, rtf; diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index dac1307a8e8f..72662aa3d934 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -10,29 +10,33 @@ const crashReporter = remote.require('electron').crashReporter; const BrowserWindow = remote.require('electron').BrowserWindow; describe('crash-reporter module', function() { - var fixtures, isCI, w; - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + beforeEach(function() { return w = new BrowserWindow({ show: false }); }); + afterEach(function() { return w.destroy(); }); + if (process.mas) { return; } - isCI = remote.getGlobal('isCi'); + + var isCI = remote.getGlobal('isCi'); if (isCI) { return; } + it('should send minidump when renderer crashes', function(done) { - var called, port, server; this.timeout(120000); - called = false; - server = http.createServer(function(req, res) { + + var called = false; + var server = http.createServer(function(req, res) { var form; server.close(); form = new multiparty.Form(); @@ -54,7 +58,7 @@ describe('crash-reporter module', function() { return done(); }); }); - port = remote.process.port; + var port = remote.process.port; return server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; @@ -72,6 +76,7 @@ describe('crash-reporter module', function() { return w.loadURL(crashUrl); }); }); + return describe(".start(options)", function() { return it('requires that the companyName and submitURL options be specified', function() { assert.throws(function() { diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 3c69d38ed327..714d5fda48c5 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -3,9 +3,9 @@ const path = require('path'); const BrowserWindow = require('electron').remote.BrowserWindow; describe('debugger module', function() { - var fixtures, w; - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + beforeEach(function() { if (w != null) { w.destroy(); @@ -16,6 +16,7 @@ describe('debugger module', function() { height: 400 }); }); + afterEach(function() { if (w != null) { w.destroy(); diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index ce5641b71cb3..6b1c99779b27 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -16,8 +16,8 @@ const comparePaths = function(path1, path2) { }; describe('ipc module', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('remote.require', function() { it('should returns same object for the same module', function() { var dialog1, dialog2; @@ -25,36 +25,39 @@ describe('ipc module', function() { dialog2 = remote.require('electron'); return assert.equal(dialog1, dialog2); }); + it('should work when object contains id property', function() { var a; a = remote.require(path.join(fixtures, 'module', 'id.js')); return assert.equal(a.id, 1127); }); + return it('should search module from the user app', function() { comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')); return comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); }); }); + describe('remote.createFunctionWithReturnValue', function() { return it('should be called in browser synchronously', function() { - var buf, call, result; - buf = new Buffer('test'); - call = remote.require(path.join(fixtures, 'module', 'call.js')); - result = call.call(remote.createFunctionWithReturnValue(buf)); + var buf = new Buffer('test'); + var call = remote.require(path.join(fixtures, 'module', 'call.js')); + var result = call.call(remote.createFunctionWithReturnValue(buf)); return assert.equal(result.constructor.name, 'Buffer'); }); }); + describe('remote object in renderer', function() { it('can change its properties', function() { - var property, property2; - property = remote.require(path.join(fixtures, 'module', 'property.js')); + var property = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property.property, 1127); property.property = 1007; assert.equal(property.property, 1007); - property2 = remote.require(path.join(fixtures, 'module', 'property.js')); + var property2 = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property2.property, 1007); return property.property = 1127; }); + return it('can construct an object from its member', function() { var call, obj; call = remote.require(path.join(fixtures, 'module', 'call.js')); @@ -62,37 +65,37 @@ describe('ipc module', function() { return assert.equal(obj.test, 'test'); }); }); + describe('remote value in browser', function() { - var print; - print = path.join(fixtures, 'module', 'print_name.js'); + var print = path.join(fixtures, 'module', 'print_name.js'); + it('keeps its constructor name for objects', function() { - var buf, print_name; - buf = new Buffer('test'); - print_name = remote.require(print); + var buf = new Buffer('test'); + var print_name = remote.require(print); return assert.equal(print_name.print(buf), 'Buffer'); }); + return it('supports instanceof Date', function() { - var now, print_name; - now = new Date(); - print_name = remote.require(print); + var now = new Date(); + var print_name = remote.require(print); assert.equal(print_name.print(now), 'Date'); return assert.deepEqual(print_name.echo(now), now); }); }); + describe('remote promise', function() { return it('can be used as promise in each side', function(done) { - var promise; - promise = remote.require(path.join(fixtures, 'module', 'promise.js')); + var promise = remote.require(path.join(fixtures, 'module', 'promise.js')); return promise.twicePromise(Promise.resolve(1234)).then(function(value) { assert.equal(value, 2468); return done(); }); }); }); + describe('ipc.sender.send', function() { return it('should work when sending an object containing id property', function(done) { - var obj; - obj = { + var obj = { id: 1, name: 'ly' }; @@ -103,16 +106,17 @@ describe('ipc module', function() { return ipcRenderer.send('message', obj); }); }); + describe('ipc.sendSync', function() { it('can be replied by setting event.returnValue', function() { - var msg; - msg = ipcRenderer.sendSync('echo', 'test'); + var msg = ipcRenderer.sendSync('echo', 'test'); return assert.equal(msg, 'test'); }); + return it('does not crash when reply is not sent and browser is destroyed', function(done) { - var w; this.timeout(10000); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false }); ipcMain.once('send-sync-message', function(event) { @@ -123,18 +127,19 @@ describe('ipc module', function() { return w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); }); }); + return describe('remote listeners', function() { - var w; - w = null; + var w = null; + afterEach(function() { return w.destroy(); }); + return it('can be added and removed correctly', function() { - var listener; w = new BrowserWindow({ show: false }); - listener = function() {}; + var listener = function() {}; w.on('test', listener); assert.equal(w.listenerCount('test'), 1); w.removeListener('test', listener); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 67705d22b3d4..292a65a0f08d 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -9,8 +9,7 @@ const MenuItem = remote.require('electron').MenuItem; describe('menu module', function() { describe('Menu.buildFromTemplate', function() { it('should be able to attach extra fields', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', extra: 'field' @@ -18,9 +17,9 @@ describe('menu module', function() { ]); return assert.equal(menu.items[0].extra, 'field'); }); + it('does not modify the specified template', function() { - var template; - template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); + var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); return assert.deepStrictEqual(template, [ { label: 'text', @@ -32,10 +31,10 @@ describe('menu module', function() { } ]); }); + return describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { it('should position before existing item', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '2', id: '2' @@ -52,9 +51,9 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); return assert.equal(menu.items[2].label, '3'); }); + it('should position after existing item', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '1', id: '1' @@ -71,9 +70,9 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); return assert.equal(menu.items[2].label, '3'); }); + it('should position at endof existing separator groups', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { type: 'separator', id: 'numbers' @@ -115,9 +114,9 @@ describe('menu module', function() { assert.equal(menu.items[6].label, 'b'); return assert.equal(menu.items[7].label, 'c'); }); + it('should create separator group if endof does not reference existing separator group', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'a', id: 'a', @@ -153,9 +152,9 @@ describe('menu module', function() { assert.equal(menu.items[6].label, '2'); return assert.equal(menu.items[7].label, '3'); }); + return it('should continue inserting items at next index when no specifier is present', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '4', id: '4' @@ -182,10 +181,10 @@ describe('menu module', function() { }); }); }); + describe('Menu.insert', function() { return it('should store item in @items by its index', function() { - var item, menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '1' }, { @@ -194,7 +193,7 @@ describe('menu module', function() { label: '3' } ]); - item = new MenuItem({ + var item = new MenuItem({ label: 'inserted' }); menu.insert(1, item); @@ -204,10 +203,10 @@ describe('menu module', function() { return assert.equal(menu.items[3].label, '3'); }); }); + describe('MenuItem.click', function() { return it('should be called with the item object passed', function(done) { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', click: function(item) { @@ -220,10 +219,10 @@ describe('menu module', function() { return menu.delegate.executeCommand(menu.items[0].commandId); }); }); + return describe('MenuItem with checked property', function() { it('clicking an checkbox item should flip the checked property', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', type: 'checkbox' @@ -233,9 +232,9 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); return assert.equal(menu.items[0].checked, true); }); + it('clicking an radio item should always make checked property true', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', type: 'radio' @@ -246,6 +245,7 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); return assert.equal(menu.items[0].checked, true); }); + it('at least have one item checked in each group', function() { var i, j, k, menu, template; template = []; @@ -269,6 +269,7 @@ describe('menu module', function() { assert.equal(menu.items[0].checked, true); return assert.equal(menu.items[12].checked, true); }); + it('should assign groupId automatically', function() { var groupId, i, j, k, l, m, menu, results, template; template = []; @@ -298,6 +299,7 @@ describe('menu module', function() { } return results; }); + return it("setting 'checked' should flip other items' 'checked' property", function() { var i, j, k, l, m, menu, n, o, p, q, results, template; template = []; diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 284033b967d8..6426e3312ecb 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -6,13 +6,13 @@ const remote = require('electron').remote; const protocol = remote.require('electron').protocol; describe('protocol module', function() { - var postData, protocolName, text; - protocolName = 'sp'; - text = 'valar morghulis'; - postData = { + var protocolName = 'sp'; + var text = 'valar morghulis'; + var postData = { name: 'post test', type: 'string' }; + afterEach(function(done) { return protocol.unregisterProtocol(protocolName, function() { return protocol.uninterceptProtocol('http', function() { @@ -20,11 +20,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.register(Any)Protocol', function() { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; + it('throws error when scheme is already registered', function(done) { return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); @@ -34,9 +35,9 @@ describe('protocol module', function() { }); }); }); + it('does not crash when handler is called twice', function(done) { - var doubleHandler; - doubleHandler = function(request, callback) { + var doubleHandler = function(request, callback) { try { callback(text); return callback(); @@ -60,6 +61,7 @@ describe('protocol module', function() { }); }); }); + it('sends error when callback is called with nothing', function(done) { return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { if (error) { @@ -77,9 +79,9 @@ describe('protocol module', function() { }); }); }); + return it('does not crash when callback is called in next tick', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return setImmediate(function() { return callback(text); }); @@ -101,6 +103,7 @@ describe('protocol module', function() { }); }); }); + describe('protocol.unregisterProtocol', function() { return it('returns error when scheme does not exist', function(done) { return protocol.unregisterProtocol('not-exist', function(error) { @@ -109,10 +112,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerStringProtocol', function() { it('sends string as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerStringProtocol(protocolName, handler, function(error) { @@ -131,9 +134,9 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerStringProtocol(protocolName, handler, function(error) { @@ -153,9 +156,9 @@ describe('protocol module', function() { }); }); }); + it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ data: text, mimeType: 'text/html' @@ -177,9 +180,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending object other than string', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -199,12 +202,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerBufferProtocol', function() { - var buffer; - buffer = new Buffer(text); + var buffer = new Buffer(text); + it('sends Buffer as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(buffer); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -223,11 +226,12 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(buffer); }; + return protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); @@ -245,9 +249,9 @@ describe('protocol module', function() { }); }); }); + it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ data: buffer, mimeType: 'text/html' @@ -269,9 +273,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending string', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -291,15 +295,15 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerFileProtocol', function() { - var fileContent, filePath, normalContent, normalPath; - filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1'); - fileContent = require('fs').readFileSync(filePath); - normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html'); - normalContent = require('fs').readFileSync(normalPath); + var filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1'); + var fileContent = require('fs').readFileSync(filePath); + var normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html'); + var normalContent = require('fs').readFileSync(normalPath); + it('sends file path as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(filePath); }; return protocol.registerFileProtocol(protocolName, handler, function(error) { @@ -318,9 +322,9 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(filePath); }; return protocol.registerFileProtocol(protocolName, handler, function(error) { @@ -363,11 +367,12 @@ describe('protocol module', function() { }); }); }); + it('can send normal file', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(normalPath); }; + return protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); @@ -384,10 +389,10 @@ describe('protocol module', function() { }); }); }); + it('fails when sending unexist-file', function(done) { - var fakeFilePath, handler; - fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); - handler = function(request, callback) { + var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); + var handler = function(request, callback) { return callback(fakeFilePath); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -406,9 +411,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending unsupported content', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -428,10 +433,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerHttpProtocol', function() { it('sends url as response', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { assert.notEqual(req.headers.accept, ''); res.end(text); return server.close(); @@ -462,9 +467,9 @@ describe('protocol module', function() { }); }); }); + it('fails when sending invalid url', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ url: 'url' }); @@ -485,9 +490,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending unsupported content', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerHttpProtocol(protocolName, handler, function(error) { @@ -507,6 +512,7 @@ describe('protocol module', function() { }); }); }); + describe('protocol.isProtocolHandled', function() { it('returns true for file:', function(done) { return protocol.isProtocolHandled('file', function(result) { @@ -514,27 +520,30 @@ describe('protocol module', function() { return done(); }); }); + it('returns true for http:', function(done) { return protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); return done(); }); }); + it('returns true for https:', function(done) { return protocol.isProtocolHandled('https', function(result) { assert.equal(result, true); return done(); }); }); + it('returns false when scheme is not registred', function(done) { return protocol.isProtocolHandled('no-exist', function(result) { assert.equal(result, false); return done(); }); }); + it('returns true for custom protocol', function(done) { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { @@ -545,9 +554,9 @@ describe('protocol module', function() { }); }); }); + return it('returns true for intercepted protocol', function(done) { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; return protocol.interceptStringProtocol('http', emptyHandler, function(error) { @@ -559,11 +568,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.intercept(Any)Protocol', function() { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; + it('throws error when scheme is already intercepted', function(done) { return protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); @@ -573,9 +583,9 @@ describe('protocol module', function() { }); }); }); + it('does not crash when handler is called twice', function(done) { - var doubleHandler; - doubleHandler = function(request, callback) { + var doubleHandler = function(request, callback) { try { callback(text); return callback(); @@ -599,6 +609,7 @@ describe('protocol module', function() { }); }); }); + return it('sends error when callback is called with nothing', function(done) { if (process.env.TRAVIS === 'true') { return done(); @@ -620,10 +631,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptStringProtocol', function() { it('can intercept http protocol', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.interceptStringProtocol('http', handler, function(error) { @@ -642,9 +653,9 @@ describe('protocol module', function() { }); }); }); + it('can set content-type', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ mimeType: 'application/json', data: '{"value": 1}' @@ -667,9 +678,9 @@ describe('protocol module', function() { }); }); }); + return it('can receive post data', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { var uploadData; uploadData = request.uploadData[0].bytes.toString(); return callback({ @@ -695,10 +706,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptBufferProtocol', function() { it('can intercept http protocol', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Buffer(text)); }; return protocol.interceptBufferProtocol('http', handler, function(error) { @@ -717,9 +728,9 @@ describe('protocol module', function() { }); }); }); + return it('can receive post data', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { var uploadData; uploadData = request.uploadData[0].bytes; return callback(uploadData); @@ -743,10 +754,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptHttpProtocol', function() { return it('can send POST request', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { var body; body = ''; req.on('data', function(chunk) { @@ -758,10 +769,9 @@ describe('protocol module', function() { return server.close(); }); return server.listen(0, '127.0.0.1', function() { - var handler, port, url; - port = server.address().port; - url = "http://127.0.0.1:" + port; - handler = function(request, callback) { + var port = server.address().port; + var url = "http://127.0.0.1:" + port; + var handler = function(request, callback) { var data; data = { url: url, @@ -794,6 +804,7 @@ describe('protocol module', function() { }); }); }); + return describe('protocol.uninterceptProtocol', function() { it('returns error when scheme does not exist', function(done) { return protocol.uninterceptProtocol('not-exist', function(error) { @@ -801,6 +812,7 @@ describe('protocol module', function() { return done(); }); }); + return it('returns error when scheme is not intercepted', function(done) { return protocol.uninterceptProtocol('http', function(error) { assert.notEqual(error, null); diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index abc127841651..9329c01823d6 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -4,16 +4,15 @@ const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { return it('returns a point object', function() { - var point; - point = screen.getCursorScreenPoint(); + var point = screen.getCursorScreenPoint(); assert.equal(typeof point.x, 'number'); return assert.equal(typeof point.y, 'number'); }); }); + return describe('screen.getPrimaryDisplay()', function() { return it('returns a display object', function() { - var display; - display = screen.getPrimaryDisplay(); + var display = screen.getPrimaryDisplay(); assert.equal(typeof display.scaleFactor, 'number'); assert(display.size.width > 0); return assert(display.size.height > 0); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index fe27f932cee0..a4421a18ed0b 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -11,11 +11,12 @@ const session = remote.session; const BrowserWindow = remote.BrowserWindow; describe('session module', function() { - var fixtures, url, w; this.timeout(10000); - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; - url = "http://127.0.0.1"; + + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + var url = "http://127.0.0.1"; + beforeEach(function() { return w = new BrowserWindow({ show: false, @@ -23,6 +24,7 @@ describe('session module', function() { height: 400 }); }); + afterEach(function() { return w.destroy(); }); @@ -62,6 +64,7 @@ describe('session module', function() { }); }); }); + it('should over-write the existent cookie', function(done) { return session.defaultSession.cookies.set({ url: url, @@ -92,6 +95,7 @@ describe('session module', function() { }); }); }); + it('should remove cookies', function(done) { return session.defaultSession.cookies.set({ url: url, @@ -155,6 +159,7 @@ describe('session module', function() { height: 400 }); }); + afterEach(function() { return w.destroy(); }); @@ -213,6 +218,7 @@ describe('session module', function() { assert(fs.existsSync(downloadFilePath)); return fs.unlinkSync(downloadFilePath); }; + it('can download using BrowserWindow.loadURL', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port; @@ -225,6 +231,7 @@ describe('session module', function() { }); }); }); + it('can download using WebView.downloadURL', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port, webview; @@ -243,6 +250,7 @@ describe('session module', function() { return document.body.appendChild(webview); }); }); + it('can cancel download', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port; diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index d3d43986ec8b..1a3eca6d5840 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -3,13 +3,11 @@ const path = require('path'); const webFrame = require('electron').webFrame; describe('webFrame module', function() { - var fixtures; - fixtures = path.resolve(__dirname, 'fixtures'); + var fixtures = path.resolve(__dirname, 'fixtures'); return describe('webFrame.registerURLSchemeAsPrivileged', function() { return it('supports fetch api', function(done) { - var url; webFrame.registerURLSchemeAsPrivileged('file'); - url = "file://" + fixtures + "/assets/logo.png"; + var url = "file://" + fixtures + "/assets/logo.png"; return fetch(url).then(function(response) { assert(response.ok); return done(); diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 91b84c77e1b3..e2a3a1ca38f7 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -5,9 +5,8 @@ const remote = require('electron').remote; const session = remote.session; describe('webRequest module', function() { - var defaultURL, server, ses; - ses = session.defaultSession; - server = http.createServer(function(req, res) { + var ses = session.defaultSession; + var server = http.createServer(function(req, res) { var content; res.setHeader('Custom', ['Header']); content = req.url; @@ -16,7 +15,8 @@ describe('webRequest module', function() { } return res.end(content); }); - defaultURL = null; + var defaultURL = null; + before(function(done) { return server.listen(0, '127.0.0.1', function() { var port; @@ -25,13 +25,16 @@ describe('webRequest module', function() { return done(); }); }); + after(function() { return server.close(); }); + describe('webRequest.onBeforeRequest', function() { afterEach(function() { return ses.webRequest.onBeforeRequest(null); }); + it('can cancel the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { return callback({ @@ -48,9 +51,9 @@ describe('webRequest module', function() { } }); }); + it('can filter URLs', function(done) { - var filter; - filter = { + var filter = { urls: [defaultURL + "filter/*"] }; ses.webRequest.onBeforeRequest(filter, function(details, callback) { @@ -77,6 +80,7 @@ describe('webRequest module', function() { } }); }); + it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { assert.equal(typeof details.id, 'number'); @@ -98,6 +102,7 @@ describe('webRequest module', function() { } }); }); + it('receives post data in details object', function(done) { var postData = { name: 'post test', @@ -125,6 +130,7 @@ describe('webRequest module', function() { } }); }); + return it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { @@ -147,10 +153,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onBeforeSendHeaders', function() { afterEach(function() { return ses.webRequest.onBeforeSendHeaders(null); }); + it('receives details object', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { assert.equal(typeof details.requestHeaders, 'object'); @@ -167,6 +175,7 @@ describe('webRequest module', function() { } }); }); + it('can change the request headers', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { var requestHeaders; @@ -187,6 +196,7 @@ describe('webRequest module', function() { } }); }); + return it('resets the whole headers', function(done) { var requestHeaders; requestHeaders = { @@ -209,10 +219,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onSendHeaders', function() { afterEach(function() { return ses.webRequest.onSendHeaders(null); }); + return it('receives details object', function(done) { ses.webRequest.onSendHeaders(function(details) { return assert.equal(typeof details.requestHeaders, 'object'); @@ -229,10 +241,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onHeadersReceived', function() { afterEach(function() { return ses.webRequest.onHeadersReceived(null); }); + it('receives details object', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); @@ -251,6 +265,7 @@ describe('webRequest module', function() { } }); }); + it('can change the response header', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { var responseHeaders; @@ -272,6 +287,7 @@ describe('webRequest module', function() { } }); }); + return it('does not change header by default', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { return callback({}); @@ -289,10 +305,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onResponseStarted', function() { afterEach(function() { return ses.webRequest.onResponseStarted(null); }); + return it('receives details object', function(done) { ses.webRequest.onResponseStarted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); @@ -313,11 +331,13 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onBeforeRedirect', function() { afterEach(function() { ses.webRequest.onBeforeRedirect(null); return ses.webRequest.onBeforeRequest(null); }); + return it('receives details object', function(done) { var redirectURL; redirectURL = defaultURL + "redirect"; @@ -348,10 +368,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onCompleted', function() { afterEach(function() { return ses.webRequest.onCompleted(null); }); + return it('receives details object', function(done) { ses.webRequest.onCompleted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); @@ -370,11 +392,13 @@ describe('webRequest module', function() { }); }); }); + return describe('webRequest.onErrorOccurred', function() { afterEach(function() { ses.webRequest.onErrorOccurred(null); return ses.webRequest.onBeforeRequest(null); }); + return it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { return callback({ diff --git a/spec/asar-spec.js b/spec/asar-spec.js index a8f449451fcf..064212e7c7e3 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -10,8 +10,8 @@ const ipcMain = remote.require('electron').ipcMain; const BrowserWindow = remote.require('electron').BrowserWindow; describe('asar package', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('node api', function() { describe('fs.readFileSync', function() { it('does not leak fd', function() { @@ -21,6 +21,7 @@ describe('asar package', function() { readCalls++; } }); + it('reads a normal file', function() { var file1, file2, file3; file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -30,6 +31,7 @@ describe('asar package', function() { file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); return assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); }); + it('reads from a empty file', function() { var buffer, file; file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); @@ -37,11 +39,13 @@ describe('asar package', function() { assert.equal(buffer.length, 0); return assert.equal(buffer.toString(), ''); }); + it('reads a linked file', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); + it('reads a file from linked directory', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); @@ -49,6 +53,7 @@ describe('asar package', function() { p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); + it('throws ENOENT error when can not find file', function() { var p, throws; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -57,6 +62,7 @@ describe('asar package', function() { }; return assert.throws(throws, /ENOENT/); }); + it('passes ENOENT error to callback when can not find file', function() { var async, p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -67,12 +73,14 @@ describe('asar package', function() { }); return async = true; }); + return it('reads a normal file with unpacked files', function() { var p; p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); return assert.equal(fs.readFileSync(p).toString().trim(), 'a'); }); }); + describe('fs.readFile', function() { it('reads a normal file', function(done) { var p; @@ -83,6 +91,7 @@ describe('asar package', function() { return done(); }); }); + it('reads from a empty file', function(done) { var p; p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); @@ -92,6 +101,7 @@ describe('asar package', function() { return done(); }); }); + it('reads a linked file', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); @@ -101,6 +111,7 @@ describe('asar package', function() { return done(); }); }); + it('reads a file from linked directory', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); @@ -110,6 +121,7 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -119,6 +131,7 @@ describe('asar package', function() { }); }); }); + describe('fs.lstatSync', function() { it('handles path with trailing slash correctly', function() { var p; @@ -126,6 +139,7 @@ describe('asar package', function() { fs.lstatSync(p); return fs.lstatSync(p + '/'); }); + it('returns information of root', function() { var p, stats; p = path.join(fixtures, 'asar', 'a.asar'); @@ -135,6 +149,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); return assert.equal(stats.size, 0); }); + it('returns information of a normal file', function() { var file, j, len, p, ref2, results, stats; ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')]; @@ -150,6 +165,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a normal directory', function() { var file, j, len, p, ref2, results, stats; ref2 = ['dir1', 'dir2', 'dir3']; @@ -165,6 +181,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a linked file', function() { var file, j, len, p, ref2, results, stats; ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')]; @@ -180,6 +197,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a linked directory', function() { var file, j, len, p, ref2, results, stats; ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')]; @@ -195,6 +213,7 @@ describe('asar package', function() { } return results; }); + return it('throws ENOENT error when can not find file', function() { var file, j, len, p, ref2, results, throws; ref2 = ['file4', 'file5', path.join('dir1', 'file4')]; @@ -210,12 +229,13 @@ describe('asar package', function() { return results; }); }); + describe('fs.lstat', function() { it('handles path with trailing slash correctly', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); return fs.lstat(p + '/', done); }); + it('returns information of root', function(done) { var p = path.join(fixtures, 'asar', 'a.asar'); fs.lstat(p, function(err, stats) { @@ -227,6 +247,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a normal file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); fs.lstat(p, function(err, stats) { @@ -238,6 +259,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a normal directory', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.lstat(p, function(err, stats) { @@ -249,6 +271,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a linked file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link1'); fs.lstat(p, function(err, stats) { @@ -260,6 +283,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a linked directory', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); fs.lstat(p, function(err, stats) { @@ -271,6 +295,7 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file4'); fs.lstat(p, function(err) { @@ -279,97 +304,97 @@ describe('asar package', function() { }); }); }); + describe('fs.realpathSync', function() { it('returns real path root', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = 'a.asar'; - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = 'a.asar'; + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a normal file', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'file1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'file1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a normal directory', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'dir1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'dir1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a linked file', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, 'a.asar', 'file1')); }); + it('returns real path of a linked directory', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link2'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link2'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, 'a.asar', 'dir1')); }); + return it('throws ENOENT error when can not find file', function() { - var p, parent, throws; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'not-exist'); - throws = function() { + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'not-exist'); + var throws = function() { return fs.realpathSync(path.join(parent, p)); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.realpath', function() { it('returns real path root', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = 'a.asar'; + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = 'a.asar'; return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a normal file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'file1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'file1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a normal directory', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'dir1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'dir1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a linked file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'file1')); return done(); }); }); + it('returns real path of a linked directory', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link2'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link2'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'dir1')); @@ -377,9 +402,8 @@ describe('asar package', function() { }); }); return it('throws ENOENT error when can not find file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'not-exist'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'not-exist'); return fs.realpath(path.join(parent, p), function(err) { assert.equal(err.code, 'ENOENT'); return done(); @@ -388,32 +412,32 @@ describe('asar package', function() { }); describe('fs.readdirSync', function() { it('reads dirs from root', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); }); + it('reads dirs from a normal dir', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); + it('reads dirs from a linked dir', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); + return it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { return fs.readdirSync(p); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.readdir', function() { it('reads dirs from root', function(done) { var p = path.join(fixtures, 'asar', 'a.asar'); @@ -423,6 +447,7 @@ describe('asar package', function() { return done(); }); }); + it('reads dirs from a normal dir', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.readdir(p, function(err, dirs) { @@ -439,15 +464,16 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.readdir(p, function(err) { assert.equal(err.code, 'ENOENT'); return done(); }); }); }); + describe('fs.openSync', function() { it('opens a normal/linked/under-linked-directory file', function() { var buffer, fd, file, j, len, p, ref2, results; @@ -464,19 +490,19 @@ describe('asar package', function() { } return results; }); + return it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { return fs.openSync(p); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.open', function() { it('opens a normal file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); return fs.open(p, 'r', function(err, fd) { var buffer; assert.equal(err, null); @@ -488,48 +514,48 @@ describe('asar package', function() { }); }); }); + return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.open(p, 'r', function(err) { assert.equal(err.code, 'ENOENT'); return done(); }); }); }); + describe('fs.mkdir', function() { return it('throws error when calling inside asar archive', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.mkdir(p, function(err) { assert.equal(err.code, 'ENOTDIR'); return done(); }); }); }); + describe('fs.mkdirSync', function() { return it('throws error when calling inside asar archive', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return assert.throws((function() { return fs.mkdirSync(p); }), new RegExp('ENOTDIR')); }); }); + describe('child_process.fork', function() { it('opens a normal js file', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); + var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); return done(); }); return child.send('message'); }); + return it('supports asar in the forked js', function(done) { - var child, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); child.on('message', function(content) { assert.equal(content, fs.readFileSync(file).toString()); return done(); @@ -537,6 +563,7 @@ describe('asar package', function() { return child.send(file); }); }); + describe('child_process.execFile', function() { var echo, execFile, execFileSync, ref2; if (process.platform !== 'darwin') { @@ -544,6 +571,7 @@ describe('asar package', function() { } ref2 = require('child_process'), execFile = ref2.execFile, execFileSync = ref2.execFileSync; echo = path.join(fixtures, 'asar', 'echo.asar', 'echo'); + it('executes binaries', function(done) { execFile(echo, ['test'], function(error, stdout) { assert.equal(error, null); @@ -551,15 +579,17 @@ describe('asar package', function() { return done(); }); }); + return xit('execFileSync executes binaries', function() { var output; output = execFileSync(echo, ['test']); return assert.equal(String(output), 'test\n'); }); }); + describe('internalModuleReadFile', function() { - var internalModuleReadFile; - internalModuleReadFile = process.binding('fs').internalModuleReadFile; + var internalModuleReadFile = process.binding('fs').internalModuleReadFile; + it('read a normal file', function() { var file1, file2, file3; file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -569,25 +599,28 @@ describe('asar package', function() { file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); return assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); }); + return it('reads a normal file with unpacked files', function() { var p; p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); return assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); }); }); + return describe('process.noAsar', function() { - var errorName; - errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; + var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; + beforeEach(function() { return process.noAsar = true; }); + afterEach(function() { return process.noAsar = false; }); + it('disables asar support in sync API', function() { - var dir, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); assert.throws((function() { return fs.readFileSync(file); }), new RegExp(errorName)); @@ -601,6 +634,7 @@ describe('asar package', function() { return fs.readdirSync(dir); }), new RegExp(errorName)); }); + it('disables asar support in async API', function(done) { var dir, file; file = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -619,6 +653,7 @@ describe('asar package', function() { }); }); }); + return it('treats *.asar as normal file', function() { var asar, content1, content2, originalFs; originalFs = require('original-fs'); @@ -632,44 +667,44 @@ describe('asar package', function() { }); }); }); + describe('asar protocol', function() { - var url; - url = require('url'); + var url = require('url'); + it('can request a file in package', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); return done(); }); }); + it('can request a file in package with unpacked files', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); + var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'a'); return done(); }); }); + it('can request a linked file in package', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); return done(); }); }); + it('can request a file in filesystem', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'file'); + var p = path.resolve(fixtures, 'asar', 'file'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file'); return done(); }); }); + it('gets 404 when file is not found', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); return $.ajax({ url: "file://" + p, error: function(err) { @@ -678,19 +713,20 @@ describe('asar package', function() { } }); }); + it('sets __dirname correctly', function(done) { - var p, u, w; after(function() { w.destroy(); return ipcMain.removeAllListeners('dirname'); }); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false, width: 400, height: 400 }); - p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html'); - u = url.format({ + var p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html'); + var u = url.format({ protocol: 'file', slashed: true, pathname: p @@ -701,19 +737,20 @@ describe('asar package', function() { }); return w.loadURL(u); }); + return it('loads script tag in html', function(done) { - var p, u, w; after(function() { w.destroy(); return ipcMain.removeAllListeners('ping'); }); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false, width: 400, height: 400 }); - p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html'); - u = url.format({ + var p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html'); + var u = url.format({ protocol: 'file', slashed: true, pathname: p @@ -725,15 +762,17 @@ describe('asar package', function() { }); }); }); + describe('original-fs module', function() { - var originalFs; - originalFs = require('original-fs'); + var originalFs = require('original-fs'); + it('treats .asar as file', function() { var file, stats; file = path.join(fixtures, 'asar', 'a.asar'); stats = originalFs.statSync(file); return assert(stats.isFile()); }); + return it('is available in forked scripts', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); @@ -744,9 +783,10 @@ describe('asar package', function() { return child.send('message'); }); }); + describe('graceful-fs module', function() { - var gfs; - gfs = require('graceful-fs'); + var gfs = require('graceful-fs'); + it('recognize asar archvies', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); @@ -756,9 +796,10 @@ describe('asar package', function() { return assert.notEqual(fs.readdir, gfs.readdir); }); }); + describe('mkdirp module', function() { - var mkdirp; - mkdirp = require('mkdirp'); + var mkdirp = require('mkdirp'); + return it('throws error when calling inside asar archive', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -767,20 +808,20 @@ describe('asar package', function() { }), new RegExp('ENOTDIR')); }); }); + return describe('native-image', function() { it('reads image from asar archive', function() { - var logo, p; - p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); - logo = nativeImage.createFromPath(p); + var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); + var logo = nativeImage.createFromPath(p); return assert.deepEqual(logo.getSize(), { width: 55, height: 55 }); }); + return it('reads image from asar archive with unpacked files', function() { - var logo, p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); - logo = nativeImage.createFromPath(p); + var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); + var logo = nativeImage.createFromPath(p); return assert.deepEqual(logo.getSize(), { width: 1024, height: 1024 diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 56fa21c89a77..21cefb0b0bcb 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -8,20 +8,22 @@ const BrowserWindow = remote.require('electron').BrowserWindow; const session = remote.require('electron').session; describe('chromium feature', function() { - var fixtures, listener; - fixtures = path.resolve(__dirname, 'fixtures'); - listener = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var listener = null; + afterEach(function() { if (listener != null) { window.removeEventListener('message', listener); } return listener = null; }); + xdescribe('heap snapshot', function() { return it('does not crash', function() { return process.atomBinding('v8_util').takeHeapSnapshot(); }); }); + describe('sending request of http protocol urls', function() { return it('does not crash', function(done) { var server; @@ -38,13 +40,15 @@ describe('chromium feature', function() { }); }); }); + describe('document.hidden', function() { - var url, w; - url = "file://" + fixtures + "/pages/document-hidden.html"; - w = null; + var url = "file://" + fixtures + "/pages/document-hidden.html"; + var w = null; + afterEach(function() { return w != null ? w.destroy() : void 0; }); + it('is set correctly when window is not shown', function(done) { w = new BrowserWindow({ show: false @@ -55,6 +59,7 @@ describe('chromium feature', function() { }); return w.loadURL(url); }); + return it('is set correctly when window is inactive', function(done) { w = new BrowserWindow({ show: false @@ -67,6 +72,7 @@ describe('chromium feature', function() { return w.loadURL(url); }); }); + xdescribe('navigator.webkitGetUserMedia', function() { return it('calls its callbacks', function(done) { this.timeout(5000); @@ -80,18 +86,21 @@ describe('chromium feature', function() { }); }); }); + describe('navigator.language', function() { return it('should not be empty', function() { return assert.notEqual(navigator.language, ''); }); }); + describe('navigator.serviceWorker', function() { - var url, w; - url = "file://" + fixtures + "/pages/service-worker/index.html"; - w = null; + var url = "file://" + fixtures + "/pages/service-worker/index.html"; + var w = null; + afterEach(function() { return w != null ? w.destroy() : void 0; }); + return it('should register for file scheme', function(done) { w = new BrowserWindow({ show: false @@ -113,8 +122,10 @@ describe('chromium feature', function() { return w.loadURL(url); }); }); + describe('window.open', function() { this.timeout(20000); + it('returns a BrowserWindowProxy object', function() { var b; b = window.open('about:blank', '', 'show=no'); @@ -122,6 +133,7 @@ describe('chromium feature', function() { assert.equal(b.constructor.name, 'BrowserWindowProxy'); return b.close(); }); + it('accepts "node-integration" as feature', function(done) { var b; listener = function(event) { @@ -132,6 +144,7 @@ describe('chromium feature', function() { window.addEventListener('message', listener); return b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); }); + it('inherit options of parent window', function(done) { var b; listener = function(event) { @@ -144,6 +157,7 @@ describe('chromium feature', function() { window.addEventListener('message', listener); return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); }); + return it('does not override child options', function(done) { var b, size; size = { @@ -159,6 +173,7 @@ describe('chromium feature', function() { return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); }); }); + describe('window.opener', function() { var url, w; this.timeout(10000); @@ -188,6 +203,7 @@ describe('chromium feature', function() { return b = window.open(url, '', 'show=no'); }); }); + describe('window.postMessage', function() { return it('sets the source and origin correctly', function(done) { var b, sourceId; @@ -211,6 +227,7 @@ describe('chromium feature', function() { }); }); }); + describe('window.opener.postMessage', function() { return it('sets source and origin correctly', function(done) { var b; @@ -225,6 +242,7 @@ describe('chromium feature', function() { return b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); }); }); + describe('creating a Uint8Array under browser side', function() { return it('does not crash', function() { var RUint8Array; @@ -232,6 +250,7 @@ describe('chromium feature', function() { return new RUint8Array; }); }); + describe('webgl', function() { return it('can be get as context in canvas', function() { var webgl; @@ -242,6 +261,7 @@ describe('chromium feature', function() { return assert.notEqual(webgl, null); }); }); + describe('web workers', function() { it('Worker can work', function(done) { var message, worker; @@ -254,6 +274,7 @@ describe('chromium feature', function() { }; return worker.postMessage(message); }); + return it('SharedWorker can work', function(done) { var message, worker; worker = new SharedWorker('../fixtures/workers/shared_worker.js'); @@ -265,15 +286,18 @@ describe('chromium feature', function() { return worker.port.postMessage(message); }); }); + describe('iframe', function() { - var iframe; - iframe = null; + var iframe = null; + beforeEach(function() { return iframe = document.createElement('iframe'); }); + afterEach(function() { return document.body.removeChild(iframe); }); + return it('does not have node integration', function(done) { iframe.src = "file://" + fixtures + "/pages/set-global.html"; document.body.appendChild(iframe); @@ -283,6 +307,7 @@ describe('chromium feature', function() { }; }); }); + describe('storage', function() { return it('requesting persitent quota works', function(done) { return navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { @@ -291,15 +316,17 @@ describe('chromium feature', function() { }); }); }); + describe('websockets', function() { - var WebSocketServer, server, wss; - wss = null; - server = null; - WebSocketServer = ws.Server; + var wss = null; + var server = null; + var WebSocketServer = ws.Server; + afterEach(function() { wss.close(); return server.close(); }); + return it('has user agent', function(done) { server = http.createServer(); return server.listen(0, '127.0.0.1', function() { @@ -319,6 +346,7 @@ describe('chromium feature', function() { }); }); }); + return describe('Promise', function() { it('resolves correctly in Node.js calls', function(done) { document.registerElement('x-element', { @@ -338,6 +366,7 @@ describe('chromium feature', function() { return called = true; }); }); + return it('resolves correctly in Electron calls', function(done) { document.registerElement('y-element', { prototype: Object.create(HTMLElement.prototype, { diff --git a/spec/modules-spec.js b/spec/modules-spec.js index 6a0471e4cea2..e3d5bd75c6d8 100644 --- a/spec/modules-spec.js +++ b/spec/modules-spec.js @@ -3,14 +3,15 @@ const path = require('path'); const temp = require('temp'); describe('third-party module', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); temp.track(); + if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { describe('runas', function() { it('can be required in renderer', function() { return require('runas'); }); + return it('can be required in node binary', function(done) { var child, runas; runas = path.join(fixtures, 'module', 'runas.js'); @@ -21,6 +22,7 @@ describe('third-party module', function() { }); }); }); + describe('ffi', function() { return it('does not crash', function() { var ffi, libm; @@ -32,6 +34,7 @@ describe('third-party module', function() { }); }); } + return describe('q', function() { var Q; Q = require('q'); diff --git a/spec/node-spec.js b/spec/node-spec.js index 6f84f59921f9..9ead92026539 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -6,8 +6,8 @@ const os = require('os'); const remote = require('electron').remote; describe('node feature', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('child_process', function() { return describe('child_process.fork', function() { it('works in current process', function(done) { @@ -19,6 +19,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('preserves args', function(done) { var args, child; args = ['--expose_gc', '-test', '1']; @@ -29,6 +30,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in forked process', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); @@ -38,6 +40,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in forked process when options.env is specifed', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { @@ -49,6 +52,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in browser process', function(done) { var child, fork; fork = remote.require('child_process').fork; @@ -59,6 +63,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('has String::localeCompare working in script', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); @@ -68,6 +73,7 @@ describe('node feature', function() { }); return child.send('message'); }); + return it('has setImmediate working in script', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); @@ -79,17 +85,20 @@ describe('node feature', function() { }); }); }); + describe('contexts', function() { describe('setTimeout in fs callback', function() { if (process.env.TRAVIS === 'true') { return; } + return it('does not crash', function(done) { return fs.readFile(__filename, function() { return setTimeout(done, 0); }); }); }); + describe('throw error in node context', function() { return it('gets caught', function(done) { var error, lsts; @@ -110,11 +119,13 @@ describe('node feature', function() { }); }); }); + describe('setTimeout called under Chromium event loop in browser process', function() { return it('can be scheduled in time', function(done) { return remote.getGlobal('setTimeout')(done, 0); }); }); + return describe('setInterval called under Chromium event loop in browser process', function() { return it('can be scheduled in time', function(done) { var clear, interval; @@ -126,11 +137,13 @@ describe('node feature', function() { }); }); }); + describe('message loop', function() { describe('process.nextTick', function() { it('emits the callback', function(done) { return process.nextTick(done); }); + return it('works in nested calls', function(done) { return process.nextTick(function() { return process.nextTick(function() { @@ -139,10 +152,12 @@ describe('node feature', function() { }); }); }); + return describe('setImmediate', function() { it('emits the callback', function(done) { return setImmediate(done); }); + return it('works in nested calls', function(done) { return setImmediate(function() { return setImmediate(function() { @@ -152,10 +167,12 @@ describe('node feature', function() { }); }); }); + describe('net.connect', function() { if (process.platform !== 'darwin') { return; } + return it('emit error when connect to a socket path without listeners', function(done) { var child, script, socketPath; socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); @@ -172,6 +189,7 @@ describe('node feature', function() { }); }); }); + describe('Buffer', function() { it('can be created from WebKit external string', function() { var b, p; @@ -181,6 +199,7 @@ describe('node feature', function() { assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); return assert.equal(Buffer.byteLength(p.innerText), 45); }); + return it('correctly parses external one-byte UTF8 string', function() { var b, p; p = document.createElement('p'); From 12adaa0570e6d8ef6a64272027d4a622ea8bc17e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:39:11 -0800 Subject: [PATCH 073/132] Remove unneeded returns --- spec/api-app-spec.js | 50 ++--- spec/api-clipboard-spec.js | 46 ++-- spec/api-crash-reporter-spec.js | 22 +- spec/api-ipc-spec.js | 57 +++-- spec/api-menu-spec.js | 46 ++-- spec/api-protocol-spec.js | 384 ++++++++++++++++---------------- spec/api-screen-spec.js | 10 +- spec/api-session-spec.js | 88 ++++---- spec/api-web-frame-spec.js | 12 +- spec/api-web-request-spec.js | 185 ++++++++------- spec/asar-spec.js | 376 +++++++++++++++---------------- spec/chromium-spec.js | 177 +++++++-------- spec/modules-spec.js | 35 ++- spec/node-spec.js | 111 +++++---- 14 files changed, 773 insertions(+), 826 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index ea305ae9535d..7b2535d54041 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -23,38 +23,38 @@ describe('electron module', function() { describe('app module', function() { describe('app.getVersion()', function() { - return it('returns the version field of package.json', function() { - return assert.equal(app.getVersion(), '0.1.0'); + it('returns the version field of package.json', function() { + assert.equal(app.getVersion(), '0.1.0'); }); }); describe('app.setVersion(version)', function() { - return it('overrides the version', function() { + it('overrides the version', function() { assert.equal(app.getVersion(), '0.1.0'); app.setVersion('test-version'); assert.equal(app.getVersion(), 'test-version'); - return app.setVersion('0.1.0'); + app.setVersion('0.1.0'); }); }); describe('app.getName()', function() { - return it('returns the name field of package.json', function() { - return assert.equal(app.getName(), 'Electron Test'); + it('returns the name field of package.json', function() { + assert.equal(app.getName(), 'Electron Test'); }); }); describe('app.setName(name)', function() { - return it('overrides the name', function() { + it('overrides the name', function() { assert.equal(app.getName(), 'Electron Test'); app.setName('test-name'); assert.equal(app.getName(), 'test-name'); - return app.setName('Electron Test'); + app.setName('Electron Test'); }); }); describe('app.getLocale()', function() { - return it('should not be empty', function() { - return assert.notEqual(app.getLocale(), ''); + it('should not be empty', function() { + assert.notEqual(app.getLocale(), ''); }); }); @@ -62,71 +62,71 @@ describe('app module', function() { var appProcess = null; afterEach(function() { - return appProcess != null ? appProcess.kill() : void 0; + appProcess != null ? appProcess.kill() : void 0; }); - return it('emits a process exit event with the code', function(done) { + it('emits a process exit event with the code', function(done) { var appPath, electronPath, output; appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); electronPath = remote.getGlobal('process').execPath; appProcess = ChildProcess.spawn(electronPath, [appPath]); output = ''; appProcess.stdout.on('data', function(data) { - return output += data; + output += data; }); - return appProcess.on('close', function(code) { + appProcess.on('close', function(code) { if (process.platform !== 'win32') { assert.notEqual(output.indexOf('Exit event with code: 123'), -1); } assert.equal(code, 123); - return done(); + done(); }); }); }); - return describe('BrowserWindow events', function() { + describe('BrowserWindow events', function() { var w = null; afterEach(function() { if (w != null) { w.destroy(); } - return w = null; + w = null; }); it('should emit browser-window-focus event when window is focused', function(done) { app.once('browser-window-focus', function(e, window) { assert.equal(w.id, window.id); - return done(); + done(); }); w = new BrowserWindow({ show: false }); - return w.emit('focus'); + w.emit('focus'); }); it('should emit browser-window-blur event when window is blured', function(done) { app.once('browser-window-blur', function(e, window) { assert.equal(w.id, window.id); - return done(); + done(); }); w = new BrowserWindow({ show: false }); - return w.emit('blur'); + w.emit('blur'); }); - return it('should emit browser-window-created event when window is created', function(done) { + it('should emit browser-window-created event when window is created', function(done) { app.once('browser-window-created', function(e, window) { - return setImmediate(function() { + setImmediate(function() { assert.equal(w.id, window.id); - return done(); + done(); }); }); w = new BrowserWindow({ show: false }); - return w.emit('blur'); + w.emit('blur'); }); }); }); diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 28afb4a5307d..0b4a9f9521cf 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -8,50 +8,46 @@ describe('clipboard module', function() { var fixtures = path.resolve(__dirname, 'fixtures'); describe('clipboard.readImage()', function() { - return it('returns NativeImage intance', function() { - var i, p; - p = path.join(fixtures, 'assets', 'logo.png'); - i = nativeImage.createFromPath(p); + it('returns NativeImage intance', function() { + var p = path.join(fixtures, 'assets', 'logo.png'); + var i = nativeImage.createFromPath(p); clipboard.writeImage(p); - return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); describe('clipboard.readText()', function() { - return it('returns unicode string correctly', function() { - var text; - text = '千江有水千江月,万里无云万里天'; + it('returns unicode string correctly', function() { + var text = '千江有水千江月,万里无云万里天'; clipboard.writeText(text); - return assert.equal(clipboard.readText(), text); + assert.equal(clipboard.readText(), text); }); }); describe('clipboard.readHtml()', function() { - return it('returns markup correctly', function() { - var markup, text; - text = 'Hi'; - markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; + it('returns markup correctly', function() { + var text = 'Hi'; + var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; clipboard.writeHtml(text); - return assert.equal(clipboard.readHtml(), markup); + assert.equal(clipboard.readHtml(), markup); }); }); describe('clipboard.readRtf', function() { - return it('returns rtf text correctly', function() { + it('returns rtf text correctly', function() { var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; clipboard.writeRtf(rtf); - return assert.equal(clipboard.readRtf(), rtf); + assert.equal(clipboard.readRtf(), rtf); }); }); - return describe('clipboard.write()', function() { - return it('returns data correctly', function() { - var i, markup, p, text, rtf; - text = 'test'; - rtf = '{\\rtf1\\utf8 text}'; - p = path.join(fixtures, 'assets', 'logo.png'); - i = nativeImage.createFromPath(p); - markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; + describe('clipboard.write()', function() { + it('returns data correctly', function() { + var text = 'test'; + var rtf = '{\\rtf1\\utf8 text}'; + var p = path.join(fixtures, 'assets', 'logo.png'); + var i = nativeImage.createFromPath(p); + var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; clipboard.write({ text: "test", html: 'Hi', @@ -61,7 +57,7 @@ describe('clipboard module', function() { assert.equal(clipboard.readText(), text); assert.equal(clipboard.readHtml(), markup); assert.equal(clipboard.readRtf(), rtf); - return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); }); diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 72662aa3d934..43830dd4ee16 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -14,13 +14,13 @@ describe('crash-reporter module', function() { var w = null; beforeEach(function() { - return w = new BrowserWindow({ + w = new BrowserWindow({ show: false }); }); afterEach(function() { - return w.destroy(); + w.destroy(); }); if (process.mas) { @@ -40,7 +40,7 @@ describe('crash-reporter module', function() { var form; server.close(); form = new multiparty.Form(); - return form.parse(req, function(error, fields) { + form.parse(req, function(error, fields) { if (called) { return; } @@ -55,11 +55,11 @@ describe('crash-reporter module', function() { assert.equal(fields['_companyName'], 'Umbrella Corporation'); assert.equal(fields['_version'], app.getVersion()); res.end('abc-123-def'); - return done(); + done(); }); }); var port = remote.process.port; - return server.listen(port, '127.0.0.1', function() { + server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; const crashUrl = url.format({ @@ -73,19 +73,19 @@ describe('crash-reporter module', function() { submitURL: "http://127.0.0.1:" + port }); } - return w.loadURL(crashUrl); + w.loadURL(crashUrl); }); }); - return describe(".start(options)", function() { - return it('requires that the companyName and submitURL options be specified', function() { + describe(".start(options)", function() { + it('requires that the companyName and submitURL options be specified', function() { assert.throws(function() { - return crashReporter.start({ + crashReporter.start({ companyName: 'Missing submitURL' }); }); - return assert.throws(function() { - return crashReporter.start({ + assert.throws(function() { + crashReporter.start({ submitURL: 'Missing companyName' }); }); diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 6b1c99779b27..25d8c925688f 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -12,7 +12,7 @@ const comparePaths = function(path1, path2) { path1 = path1.toLowerCase(); path2 = path2.toLowerCase(); } - return assert.equal(path1, path2); + assert.equal(path1, path2); }; describe('ipc module', function() { @@ -23,27 +23,26 @@ describe('ipc module', function() { var dialog1, dialog2; dialog1 = remote.require('electron'); dialog2 = remote.require('electron'); - return assert.equal(dialog1, dialog2); + assert.equal(dialog1, dialog2); }); it('should work when object contains id property', function() { - var a; - a = remote.require(path.join(fixtures, 'module', 'id.js')); - return assert.equal(a.id, 1127); + var a = remote.require(path.join(fixtures, 'module', 'id.js')); + assert.equal(a.id, 1127); }); - return it('should search module from the user app', function() { + it('should search module from the user app', function() { comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')); - return comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); + comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); }); }); describe('remote.createFunctionWithReturnValue', function() { - return it('should be called in browser synchronously', function() { + it('should be called in browser synchronously', function() { var buf = new Buffer('test'); var call = remote.require(path.join(fixtures, 'module', 'call.js')); var result = call.call(remote.createFunctionWithReturnValue(buf)); - return assert.equal(result.constructor.name, 'Buffer'); + assert.equal(result.constructor.name, 'Buffer'); }); }); @@ -55,14 +54,14 @@ describe('ipc module', function() { assert.equal(property.property, 1007); var property2 = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property2.property, 1007); - return property.property = 1127; + property.property = 1127; }); - return it('can construct an object from its member', function() { + it('can construct an object from its member', function() { var call, obj; call = remote.require(path.join(fixtures, 'module', 'call.js')); obj = new call.constructor; - return assert.equal(obj.test, 'test'); + assert.equal(obj.test, 'test'); }); }); @@ -72,48 +71,48 @@ describe('ipc module', function() { it('keeps its constructor name for objects', function() { var buf = new Buffer('test'); var print_name = remote.require(print); - return assert.equal(print_name.print(buf), 'Buffer'); + assert.equal(print_name.print(buf), 'Buffer'); }); - return it('supports instanceof Date', function() { + it('supports instanceof Date', function() { var now = new Date(); var print_name = remote.require(print); assert.equal(print_name.print(now), 'Date'); - return assert.deepEqual(print_name.echo(now), now); + assert.deepEqual(print_name.echo(now), now); }); }); describe('remote promise', function() { - return it('can be used as promise in each side', function(done) { + it('can be used as promise in each side', function(done) { var promise = remote.require(path.join(fixtures, 'module', 'promise.js')); - return promise.twicePromise(Promise.resolve(1234)).then(function(value) { + promise.twicePromise(Promise.resolve(1234)).then(function(value) { assert.equal(value, 2468); - return done(); + done(); }); }); }); describe('ipc.sender.send', function() { - return it('should work when sending an object containing id property', function(done) { + it('should work when sending an object containing id property', function(done) { var obj = { id: 1, name: 'ly' }; ipcRenderer.once('message', function(event, message) { assert.deepEqual(message, obj); - return done(); + done(); }); - return ipcRenderer.send('message', obj); + ipcRenderer.send('message', obj); }); }); describe('ipc.sendSync', function() { it('can be replied by setting event.returnValue', function() { var msg = ipcRenderer.sendSync('echo', 'test'); - return assert.equal(msg, 'test'); + assert.equal(msg, 'test'); }); - return it('does not crash when reply is not sent and browser is destroyed', function(done) { + it('does not crash when reply is not sent and browser is destroyed', function(done) { this.timeout(10000); var w = new BrowserWindow({ @@ -122,20 +121,20 @@ describe('ipc module', function() { ipcMain.once('send-sync-message', function(event) { event.returnValue = null; w.destroy(); - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); }); }); - return describe('remote listeners', function() { + describe('remote listeners', function() { var w = null; afterEach(function() { - return w.destroy(); + w.destroy(); }); - return it('can be added and removed correctly', function() { + it('can be added and removed correctly', function() { w = new BrowserWindow({ show: false }); @@ -143,7 +142,7 @@ describe('ipc module', function() { w.on('test', listener); assert.equal(w.listenerCount('test'), 1); w.removeListener('test', listener); - return assert.equal(w.listenerCount('test'), 0); + assert.equal(w.listenerCount('test'), 0); }); }); }); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 292a65a0f08d..60464c732754 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -15,12 +15,12 @@ describe('menu module', function() { extra: 'field' } ]); - return assert.equal(menu.items[0].extra, 'field'); + assert.equal(menu.items[0].extra, 'field'); }); it('does not modify the specified template', function() { var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); - return assert.deepStrictEqual(template, [ + assert.deepStrictEqual(template, [ { label: 'text', submenu: [ @@ -32,7 +32,7 @@ describe('menu module', function() { ]); }); - return describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { + describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { it('should position before existing item', function() { var menu = Menu.buildFromTemplate([ { @@ -49,7 +49,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, '2'); - return assert.equal(menu.items[2].label, '3'); + assert.equal(menu.items[2].label, '3'); }); it('should position after existing item', function() { @@ -68,7 +68,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, '2'); - return assert.equal(menu.items[2].label, '3'); + assert.equal(menu.items[2].label, '3'); }); it('should position at endof existing separator groups', function() { @@ -112,7 +112,7 @@ describe('menu module', function() { assert.equal(menu.items[4].id, 'letters'); assert.equal(menu.items[5].label, 'a'); assert.equal(menu.items[6].label, 'b'); - return assert.equal(menu.items[7].label, 'c'); + assert.equal(menu.items[7].label, 'c'); }); it('should create separator group if endof does not reference existing separator group', function() { @@ -150,10 +150,10 @@ describe('menu module', function() { assert.equal(menu.items[4].id, 'numbers'); assert.equal(menu.items[5].label, '1'); assert.equal(menu.items[6].label, '2'); - return assert.equal(menu.items[7].label, '3'); + assert.equal(menu.items[7].label, '3'); }); - return it('should continue inserting items at next index when no specifier is present', function() { + it('should continue inserting items at next index when no specifier is present', function() { var menu = Menu.buildFromTemplate([ { label: '4', @@ -177,13 +177,13 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); assert.equal(menu.items[2].label, '3'); assert.equal(menu.items[3].label, '4'); - return assert.equal(menu.items[4].label, '5'); + assert.equal(menu.items[4].label, '5'); }); }); }); describe('Menu.insert', function() { - return it('should store item in @items by its index', function() { + it('should store item in @items by its index', function() { var menu = Menu.buildFromTemplate([ { label: '1' @@ -200,27 +200,27 @@ describe('menu module', function() { assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, 'inserted'); assert.equal(menu.items[2].label, '2'); - return assert.equal(menu.items[3].label, '3'); + assert.equal(menu.items[3].label, '3'); }); }); describe('MenuItem.click', function() { - return it('should be called with the item object passed', function(done) { + it('should be called with the item object passed', function(done) { var menu = Menu.buildFromTemplate([ { label: 'text', click: function(item) { assert.equal(item.constructor.name, 'MenuItem'); assert.equal(item.label, 'text'); - return done(); + done(); } } ]); - return menu.delegate.executeCommand(menu.items[0].commandId); + menu.delegate.executeCommand(menu.items[0].commandId); }); }); - return describe('MenuItem with checked property', function() { + describe('MenuItem with checked property', function() { it('clicking an checkbox item should flip the checked property', function() { var menu = Menu.buildFromTemplate([ { @@ -230,7 +230,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].checked, false); menu.delegate.executeCommand(menu.items[0].commandId); - return assert.equal(menu.items[0].checked, true); + assert.equal(menu.items[0].checked, true); }); it('clicking an radio item should always make checked property true', function() { @@ -243,7 +243,7 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); assert.equal(menu.items[0].checked, true); menu.delegate.executeCommand(menu.items[0].commandId); - return assert.equal(menu.items[0].checked, true); + assert.equal(menu.items[0].checked, true); }); it('at least have one item checked in each group', function() { @@ -267,7 +267,7 @@ describe('menu module', function() { menu = Menu.buildFromTemplate(template); menu.delegate.menuWillShow(); assert.equal(menu.items[0].checked, true); - return assert.equal(menu.items[12].checked, true); + assert.equal(menu.items[12].checked, true); }); it('should assign groupId automatically', function() { @@ -293,14 +293,12 @@ describe('menu module', function() { for (i = l = 0; l <= 10; i = ++l) { assert.equal(menu.items[i].groupId, groupId); } - results = []; for (i = m = 12; m <= 20; i = ++m) { - results.push(assert.equal(menu.items[i].groupId, groupId + 1)); + assert.equal(menu.items[i].groupId, groupId + 1); } - return results; }); - return it("setting 'checked' should flip other items' 'checked' property", function() { + it("setting 'checked' should flip other items' 'checked' property", function() { var i, j, k, l, m, menu, n, o, p, q, results, template; template = []; for (i = j = 0; j <= 10; i = ++j) { @@ -341,11 +339,9 @@ describe('menu module', function() { assert.equal(menu.items[i].checked, false); } assert.equal(menu.items[12].checked, true); - results = []; for (i = q = 13; q <= 20; i = ++q) { - results.push(assert.equal(menu.items[i].checked, false)); + assert.equal(menu.items[i].checked, false); } - return results; }); }); }); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 6426e3312ecb..a7de60d8c36b 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -14,24 +14,24 @@ describe('protocol module', function() { }; afterEach(function(done) { - return protocol.unregisterProtocol(protocolName, function() { - return protocol.uninterceptProtocol('http', function() { - return done(); + protocol.unregisterProtocol(protocolName, function() { + protocol.uninterceptProtocol('http', function() { + done(); }); }); }); describe('protocol.register(Any)Protocol', function() { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; it('throws error when scheme is already registered', function(done) { - return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { + protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); - return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { + protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -40,34 +40,34 @@ describe('protocol module', function() { var doubleHandler = function(request, callback) { try { callback(text); - return callback(); + callback(); } catch (error) { // Ignore error } }; - return protocol.registerStringProtocol(protocolName, doubleHandler, function(error) { + protocol.registerStringProtocol(protocolName, doubleHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); it('sends error when callback is called with nothing', function(done) { - return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { + protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { return done('request succeeded but it should not'); @@ -80,24 +80,24 @@ describe('protocol module', function() { }); }); - return it('does not crash when callback is called in next tick', function(done) { + it('does not crash when callback is called in next tick', function(done) { var handler = function(request, callback) { - return setImmediate(function() { - return callback(text); + setImmediate(function() { + callback(text); }); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -105,10 +105,10 @@ describe('protocol module', function() { }); describe('protocol.unregisterProtocol', function() { - return it('returns error when scheme does not exist', function(done) { - return protocol.unregisterProtocol('not-exist', function(error) { + it('returns error when scheme does not exist', function(done) { + protocol.unregisterProtocol('not-exist', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -116,9 +116,9 @@ describe('protocol module', function() { describe('protocol.registerStringProtocol', function() { it('sends string as response', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } @@ -126,10 +126,10 @@ describe('protocol module', function() { url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -137,21 +137,21 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, text); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -159,44 +159,44 @@ describe('protocol module', function() { it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ data: text, mimeType: 'text/html' }); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('fails when sending object other than string', function(done) { + it('fails when sending object other than string', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -208,20 +208,20 @@ describe('protocol module', function() { it('sends Buffer as response', function(done) { var handler = function(request, callback) { - return callback(buffer); + callback(buffer); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -229,22 +229,22 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(buffer); + callback(buffer); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, text); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -252,44 +252,44 @@ describe('protocol module', function() { it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ data: buffer, mimeType: 'text/html' }); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('fails when sending string', function(done) { + it('fails when sending string', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -304,9 +304,9 @@ describe('protocol module', function() { it('sends file path as response', function(done) { var handler = function(request, callback) { - return callback(filePath); + callback(filePath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } @@ -327,42 +327,41 @@ describe('protocol module', function() { var handler = function(request, callback) { return callback(filePath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, String(fileContent)); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ path: filePath }); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(fileContent)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -370,21 +369,21 @@ describe('protocol module', function() { it('can send normal file', function(done) { var handler = function(request, callback) { - return callback(normalPath); + callback(normalPath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(normalContent)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -393,41 +392,41 @@ describe('protocol module', function() { it('fails when sending unexist-file', function(done) { var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); var handler = function(request, callback) { - return callback(fakeFilePath); + callback(fakeFilePath); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); }); - return it('fails when sending unsupported content', function(done) { + it('fails when sending unsupported content', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -439,29 +438,28 @@ describe('protocol module', function() { var server = http.createServer(function(req, res) { assert.notEqual(req.headers.accept, ''); res.end(text); - return server.close(); + server.close(); }); return server.listen(0, '127.0.0.1', function() { - var handler, port, url; - port = server.address().port; - url = "http://127.0.0.1:" + port; - handler = function(request, callback) { - return callback({ + var port = server.address().port; + var url = "http://127.0.0.1:" + port; + var handler = function(request, callback) { + callback({ url: url }); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -470,43 +468,43 @@ describe('protocol module', function() { it('fails when sending invalid url', function(done) { var handler = function(request, callback) { - return callback({ + callback({ url: 'url' }); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); }); - return it('fails when sending unsupported content', function(done) { + it('fails when sending unsupported content', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -515,55 +513,55 @@ describe('protocol module', function() { describe('protocol.isProtocolHandled', function() { it('returns true for file:', function(done) { - return protocol.isProtocolHandled('file', function(result) { + protocol.isProtocolHandled('file', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns true for http:', function(done) { - return protocol.isProtocolHandled('http', function(result) { + protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns true for https:', function(done) { - return protocol.isProtocolHandled('https', function(result) { + protocol.isProtocolHandled('https', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns false when scheme is not registred', function(done) { - return protocol.isProtocolHandled('no-exist', function(result) { + protocol.isProtocolHandled('no-exist', function(result) { assert.equal(result, false); - return done(); + done(); }); }); it('returns true for custom protocol', function(done) { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; - return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { + protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); - return protocol.isProtocolHandled(protocolName, function(result) { + protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); - return done(); + done(); }); }); }); - return it('returns true for intercepted protocol', function(done) { + it('returns true for intercepted protocol', function(done) { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; - return protocol.interceptStringProtocol('http', emptyHandler, function(error) { + protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); - return protocol.isProtocolHandled('http', function(result) { + protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); - return done(); + done(); }); }); }); @@ -571,15 +569,15 @@ describe('protocol module', function() { describe('protocol.intercept(Any)Protocol', function() { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; it('throws error when scheme is already intercepted', function(done) { - return protocol.interceptStringProtocol('http', emptyHandler, function(error) { + protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); - return protocol.interceptBufferProtocol('http', emptyHandler, function(error) { + protocol.interceptBufferProtocol('http', emptyHandler, function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -593,39 +591,39 @@ describe('protocol module', function() { // Ignore error } }; - return protocol.interceptStringProtocol('http', doubleHandler, function(error) { + protocol.interceptStringProtocol('http', doubleHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('sends error when callback is called with nothing', function(done) { + it('sends error when callback is called with nothing', function(done) { if (process.env.TRAVIS === 'true') { return done(); } - return protocol.interceptBufferProtocol('http', emptyHandler, function(error) { + protocol.interceptBufferProtocol('http', emptyHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -635,20 +633,20 @@ describe('protocol module', function() { describe('protocol.interceptStringProtocol', function() { it('can intercept http protocol', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -656,51 +654,50 @@ describe('protocol module', function() { it('can set content-type', function(done) { var handler = function(request, callback) { - return callback({ + callback({ mimeType: 'application/json', data: '{"value": 1}' }); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(typeof data, 'object'); assert.equal(data.value, 1); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('can receive post data', function(done) { + it('can receive post data', function(done) { var handler = function(request, callback) { - var uploadData; - uploadData = request.uploadData[0].bytes.toString(); - return callback({ + var uploadData = request.uploadData[0].bytes.toString(); + callback({ data: uploadData }); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.deepEqual(qs.parse(data), postData); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -710,45 +707,44 @@ describe('protocol module', function() { describe('protocol.interceptBufferProtocol', function() { it('can intercept http protocol', function(done) { var handler = function(request, callback) { - return callback(new Buffer(text)); + callback(new Buffer(text)); }; - return protocol.interceptBufferProtocol('http', handler, function(error) { + protocol.interceptBufferProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('can receive post data', function(done) { + it('can receive post data', function(done) { var handler = function(request, callback) { - var uploadData; - uploadData = request.uploadData[0].bytes; - return callback(uploadData); + var uploadData = request.uploadData[0].bytes; + callback(uploadData); }; - return protocol.interceptBufferProtocol('http', handler, function(error) { + protocol.interceptBufferProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.equal(data, $.param(postData)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -756,24 +752,22 @@ describe('protocol module', function() { }); describe('protocol.interceptHttpProtocol', function() { - return it('can send POST request', function(done) { + it('can send POST request', function(done) { var server = http.createServer(function(req, res) { - var body; - body = ''; + var body = ''; req.on('data', function(chunk) { - return body += chunk; + body += chunk; }); req.on('end', function() { - return res.end(body); + res.end(body); }); - return server.close(); + server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; var url = "http://127.0.0.1:" + port; var handler = function(request, callback) { - var data; - data = { + var data = { url: url, method: 'POST', uploadData: { @@ -782,22 +776,22 @@ describe('protocol module', function() { }, session: null }; - return callback(data); + callback(data); }; - return protocol.interceptHttpProtocol('http', handler, function(error) { + protocol.interceptHttpProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.deepEqual(qs.parse(data), postData); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -805,18 +799,18 @@ describe('protocol module', function() { }); }); - return describe('protocol.uninterceptProtocol', function() { + describe('protocol.uninterceptProtocol', function() { it('returns error when scheme does not exist', function(done) { - return protocol.uninterceptProtocol('not-exist', function(error) { + protocol.uninterceptProtocol('not-exist', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); - return it('returns error when scheme is not intercepted', function(done) { - return protocol.uninterceptProtocol('http', function(error) { + it('returns error when scheme is not intercepted', function(done) { + protocol.uninterceptProtocol('http', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index 9329c01823d6..34828e863e82 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -3,19 +3,19 @@ const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { - return it('returns a point object', function() { + it('returns a point object', function() { var point = screen.getCursorScreenPoint(); assert.equal(typeof point.x, 'number'); - return assert.equal(typeof point.y, 'number'); + assert.equal(typeof point.y, 'number'); }); }); - return describe('screen.getPrimaryDisplay()', function() { - return it('returns a display object', function() { + describe('screen.getPrimaryDisplay()', function() { + it('returns a display object', function() { var display = screen.getPrimaryDisplay(); assert.equal(typeof display.scaleFactor, 'number'); assert(display.size.width > 0); - return assert(display.size.height > 0); + assert(display.size.height > 0); }); }); }); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index a4421a18ed0b..049309eda589 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -18,7 +18,7 @@ describe('session module', function() { var url = "http://127.0.0.1"; beforeEach(function() { - return w = new BrowserWindow({ + w = new BrowserWindow({ show: false, width: 400, height: 400 @@ -26,7 +26,7 @@ describe('session module', function() { }); afterEach(function() { - return w.destroy(); + w.destroy(); }); describe('session.cookies', function() { @@ -35,14 +35,14 @@ describe('session module', function() { server = http.createServer(function(req, res) { res.setHeader('Set-Cookie', ['0=0']); res.end('finished'); - return server.close(); + server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; w.loadURL(url + ":" + port); - return w.webContents.on('did-finish-load', function() { - return w.webContents.session.cookies.get({ + w.webContents.on('did-finish-load', function() { + w.webContents.session.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -59,14 +59,14 @@ describe('session module', function() { } } } - return done('Can not find cookie'); + done('Can not find cookie'); }); }); }); }); it('should over-write the existent cookie', function(done) { - return session.defaultSession.cookies.set({ + session.defaultSession.cookies.set({ url: url, name: '1', value: '1' @@ -74,7 +74,7 @@ describe('session module', function() { if (error) { return done(error); } - return session.defaultSession.cookies.get({ + session.defaultSession.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -91,13 +91,13 @@ describe('session module', function() { } } } - return done('Can not find cookie'); + done('Can not find cookie'); }); }); }); it('should remove cookies', function(done) { - return session.defaultSession.cookies.set({ + session.defaultSession.cookies.set({ url: url, name: '2', value: '2' @@ -105,8 +105,8 @@ describe('session module', function() { if (error) { return done(error); } - return session.defaultSession.cookies.remove(url, '2', function() { - return session.defaultSession.cookies.get({ + session.defaultSession.cookies.remove(url, '2', function() { + session.defaultSession.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -119,7 +119,7 @@ describe('session module', function() { return done('Cookie not deleted'); } } - return done(); + done(); }); }); }); @@ -128,22 +128,22 @@ describe('session module', function() { describe('session.clearStorageData(options)', function() { fixtures = path.resolve(__dirname, 'fixtures'); - return it('clears localstorage data', function(done) { + it('clears localstorage data', function(done) { ipcMain.on('count', function(event, count) { ipcMain.removeAllListeners('count'); assert(!count); - return done(); + done(); }); w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')); - return w.webContents.on('did-finish-load', function() { + w.webContents.on('did-finish-load', function() { var options; options = { origin: "file://", storages: ['localstorage'], quotas: ['persistent'] }; - return w.webContents.session.clearStorageData(options, function() { - return w.webContents.send('getcount'); + w.webContents.session.clearStorageData(options, function() { + w.webContents.send('getcount'); }); }); }); @@ -161,7 +161,7 @@ describe('session module', function() { }); afterEach(function() { - return w.destroy(); + w.destroy(); }); it('can cancel default download behavior', function(done) { @@ -193,21 +193,20 @@ describe('session module', function() { }); }); - return describe('DownloadItem', function() { - var assertDownload, contentDisposition, downloadFilePath, downloadServer, mockPDF; - mockPDF = new Buffer(1024 * 1024 * 5); - contentDisposition = 'inline; filename="mock.pdf"'; - downloadFilePath = path.join(fixtures, 'mock.pdf'); - downloadServer = http.createServer(function(req, res) { + describe('DownloadItem', function() { + var mockPDF = new Buffer(1024 * 1024 * 5); + var contentDisposition = 'inline; filename="mock.pdf"'; + var downloadFilePath = path.join(fixtures, 'mock.pdf'); + var downloadServer = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Length': mockPDF.length, 'Content-Type': 'application/pdf', 'Content-Disposition': contentDisposition }); res.end(mockPDF); - return downloadServer.close(); + downloadServer.close(); }); - assertDownload = function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { + var assertDownload = function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { assert.equal(state, 'completed'); assert.equal(filename, 'mock.pdf'); assert.equal(url, "http://127.0.0.1:" + port + "/"); @@ -216,55 +215,52 @@ describe('session module', function() { assert.equal(totalBytes, mockPDF.length); assert.equal(disposition, contentDisposition); assert(fs.existsSync(downloadFilePath)); - return fs.unlinkSync(downloadFilePath); + fs.unlinkSync(downloadFilePath); }; it('can download using BrowserWindow.loadURL', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', false, false); w.loadURL(url + ":" + port); - return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); - return done(); + done(); }); }); }); it('can download using WebView.downloadURL', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port, webview; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', false, false); - webview = new WebView; + var webview = new WebView; webview.src = "file://" + fixtures + "/api/blank.html"; webview.addEventListener('did-finish-load', function() { - return webview.downloadURL(url + ":" + port + "/"); + webview.downloadURL(url + ":" + port + "/"); }); ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); document.body.removeChild(webview); - return done(); + done(); }); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); it('can cancel download', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', true, false); w.loadURL(url + ":" + port + "/"); - return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assert.equal(state, 'cancelled'); assert.equal(filename, 'mock.pdf'); assert.equal(mimeType, 'application/pdf'); assert.equal(receivedBytes, 0); assert.equal(totalBytes, mockPDF.length); assert.equal(disposition, contentDisposition); - return done(); + done(); }); }); }); diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 1a3eca6d5840..15f31aa8f095 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -4,15 +4,15 @@ const webFrame = require('electron').webFrame; describe('webFrame module', function() { var fixtures = path.resolve(__dirname, 'fixtures'); - return describe('webFrame.registerURLSchemeAsPrivileged', function() { - return it('supports fetch api', function(done) { + describe('webFrame.registerURLSchemeAsPrivileged', function() { + it('supports fetch api', function(done) { webFrame.registerURLSchemeAsPrivileged('file'); var url = "file://" + fixtures + "/assets/logo.png"; - return fetch(url).then(function(response) { + fetch(url).then(function(response) { assert(response.ok); - return done(); - })["catch"](function(err) { - return done('unexpected error : ' + err); + done(); + }).catch(function(err) { + done('unexpected error : ' + err); }); }); }); diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index e2a3a1ca38f7..f64c91b610c5 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -13,41 +13,41 @@ describe('webRequest module', function() { if (req.headers.accept === '*/*;test/header') { content += 'header/received'; } - return res.end(content); + res.end(content); }); var defaultURL = null; before(function(done) { - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; defaultURL = "http://127.0.0.1:" + port + "/"; - return done(); + done(); }); }); after(function() { - return server.close(); + server.close(); }); describe('webRequest.onBeforeRequest', function() { afterEach(function() { - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); it('can cancel the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function() { - return done('unexpected success'); + done('unexpected success'); }, error: function() { - return done(); + done(); } }); }); @@ -57,26 +57,26 @@ describe('webRequest module', function() { urls: [defaultURL + "filter/*"] }; ses.webRequest.onBeforeRequest(filter, function(details, callback) { - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL + "nofilter/test", success: function(data) { assert.equal(data, '/nofilter/test'); - return $.ajax({ + $.ajax({ url: defaultURL + "filter/test", success: function() { - return done('unexpected success'); + done('unexpected success'); }, error: function() { - return done(); + done(); } }); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -89,16 +89,16 @@ describe('webRequest module', function() { assert.equal(details.method, 'GET'); assert.equal(details.resourceType, 'xhr'); assert(!details.uploadData); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -115,11 +115,11 @@ describe('webRequest module', function() { assert.equal(details.uploadData.length, 1); data = qs.parse(details.uploadData[0].bytes.toString()); assert.deepEqual(data, postData); - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL, type: 'POST', data: postData, @@ -131,24 +131,24 @@ describe('webRequest module', function() { }); }); - return it('can redirect the request', function(done) { + it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { - return callback({ + callback({ redirectURL: defaultURL + "redirect" }); } else { - return callback({}); + callback({}); } }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/redirect'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -156,22 +156,22 @@ describe('webRequest module', function() { describe('webRequest.onBeforeSendHeaders', function() { afterEach(function() { - return ses.webRequest.onBeforeSendHeaders(null); + ses.webRequest.onBeforeSendHeaders(null); }); it('receives details object', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { assert.equal(typeof details.requestHeaders, 'object'); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -181,40 +181,39 @@ describe('webRequest module', function() { var requestHeaders; requestHeaders = details.requestHeaders; requestHeaders.Accept = '*/*;test/header'; - return callback({ + callback({ requestHeaders: requestHeaders }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/header/received'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); - return it('resets the whole headers', function(done) { - var requestHeaders; - requestHeaders = { + it('resets the whole headers', function(done) { + var requestHeaders = { Test: 'header' }; ses.webRequest.onBeforeSendHeaders(function(details, callback) { - return callback({ + callback({ requestHeaders: requestHeaders }); }); ses.webRequest.onSendHeaders(function(details) { assert.deepEqual(details.requestHeaders, requestHeaders); - return done(); + done(); }); - return $.ajax({ + $.ajax({ url: defaultURL, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -222,21 +221,21 @@ describe('webRequest module', function() { describe('webRequest.onSendHeaders', function() { afterEach(function() { - return ses.webRequest.onSendHeaders(null); + ses.webRequest.onSendHeaders(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onSendHeaders(function(details) { - return assert.equal(typeof details.requestHeaders, 'object'); + assert.equal(typeof details.requestHeaders, 'object'); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -244,7 +243,7 @@ describe('webRequest module', function() { describe('webRequest.onHeadersReceived', function() { afterEach(function() { - return ses.webRequest.onHeadersReceived(null); + ses.webRequest.onHeadersReceived(null); }); it('receives details object', function(done) { @@ -252,55 +251,54 @@ describe('webRequest module', function() { assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); assert.equal(details.statusCode, 200); assert.equal(details.responseHeaders['Custom'], 'Header'); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); it('can change the response header', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { - var responseHeaders; - responseHeaders = details.responseHeaders; + var responseHeaders = details.responseHeaders; responseHeaders['Custom'] = ['Changed']; - return callback({ + callback({ responseHeaders: responseHeaders }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Changed'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); - return it('does not change header by default', function(done) { + it('does not change header by default', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Header'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -308,25 +306,25 @@ describe('webRequest module', function() { describe('webRequest.onResponseStarted', function() { afterEach(function() { - return ses.webRequest.onResponseStarted(null); + ses.webRequest.onResponseStarted(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onResponseStarted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); assert.equal(details.statusCode, 200); - return assert.equal(details.responseHeaders['Custom'], 'Header'); + assert.equal(details.responseHeaders['Custom'], 'Header'); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Header'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -335,35 +333,34 @@ describe('webRequest module', function() { describe('webRequest.onBeforeRedirect', function() { afterEach(function() { ses.webRequest.onBeforeRedirect(null); - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); - return it('receives details object', function(done) { - var redirectURL; - redirectURL = defaultURL + "redirect"; + it('receives details object', function(done) { + var redirectURL = defaultURL + "redirect"; ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { - return callback({ + callback({ redirectURL: redirectURL }); } else { - return callback({}); + callback({}); } }); ses.webRequest.onBeforeRedirect(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 307 Internal Redirect'); assert.equal(details.statusCode, 307); - return assert.equal(details.redirectURL, redirectURL); + assert.equal(details.redirectURL, redirectURL); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/redirect'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -371,48 +368,48 @@ describe('webRequest module', function() { describe('webRequest.onCompleted', function() { afterEach(function() { - return ses.webRequest.onCompleted(null); + ses.webRequest.onCompleted(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onCompleted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); - return assert.equal(details.statusCode, 200); + assert.equal(details.statusCode, 200); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); }); - return describe('webRequest.onErrorOccurred', function() { + describe('webRequest.onErrorOccurred', function() { afterEach(function() { ses.webRequest.onErrorOccurred(null); - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { - return callback({ + callback({ cancel: true }); }); ses.webRequest.onErrorOccurred(function(details) { assert.equal(details.error, 'net::ERR_BLOCKED_BY_CLIENT'); - return done(); + done(); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function() { - return done('unexpected success'); + done('unexpected success'); } }); }); diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 064212e7c7e3..d35cf186c65a 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -23,121 +23,108 @@ describe('asar package', function() { }); it('reads a normal file', function() { - var file1, file2, file3; - file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); assert.equal(fs.readFileSync(file1).toString().trim(), 'file1'); - file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); assert.equal(fs.readFileSync(file2).toString().trim(), 'file2'); - file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - return assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); + assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); }); it('reads from a empty file', function() { - var buffer, file; - file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - buffer = fs.readFileSync(file); + var file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); + var buffer = fs.readFileSync(file); assert.equal(buffer.length, 0); - return assert.equal(buffer.toString(), ''); + assert.equal(buffer.toString(), ''); }); it('reads a linked file', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); it('reads a file from linked directory', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); + assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { - return fs.readFileSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { + fs.readFileSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); it('passes ENOENT error to callback when can not find file', function() { - var async, p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - async = false; + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var async = false; fs.readFile(p, function(e) { assert(async); - return assert(/ENOENT/.test(e)); + assert(/ENOENT/.test(e)); }); - return async = true; + async = true; }); - return it('reads a normal file with unpacked files', function() { - var p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'a'); + it('reads a normal file with unpacked files', function() { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); + assert.equal(fs.readFileSync(p).toString().trim(), 'a'); }); }); describe('fs.readFile', function() { it('reads a normal file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); it('reads from a empty file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content), ''); - return done(); + done(); }); }); it('reads a linked file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); it('reads a file from linked directory', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.readFile(p, function(err) { + it('throws ENOENT error when can not find file', function(done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + fs.readFile(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); describe('fs.lstatSync', function() { it('handles path with trailing slash correctly', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); fs.lstatSync(p); - return fs.lstatSync(p + '/'); + fs.lstatSync(p + '/'); }); it('returns information of root', function() { @@ -147,7 +134,7 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); - return assert.equal(stats.size, 0); + assert.equal(stats.size, 0); }); it('returns information of a normal file', function() { @@ -163,7 +150,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); results.push(assert.equal(stats.size, 6)); } - return results; + results; }); it('returns information of a normal directory', function() { @@ -179,7 +166,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); it('returns information of a linked file', function() { @@ -195,7 +182,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), true); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); it('returns information of a linked directory', function() { @@ -211,29 +198,27 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), true); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); - return it('throws ENOENT error when can not find file', function() { - var file, j, len, p, ref2, results, throws; + it('throws ENOENT error when can not find file', function() { + var file, j, len, p, ref2, throws; ref2 = ['file4', 'file5', path.join('dir1', 'file4')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); throws = function() { - return fs.lstatSync(p); + fs.lstatSync(p); }; - results.push(assert.throws(throws, /ENOENT/)); + assert.throws(throws, /ENOENT/); } - return results; }); }); describe('fs.lstat', function() { it('handles path with trailing slash correctly', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return fs.lstat(p + '/', done); + fs.lstat(p + '/', done); }); it('returns information of root', function(done) { @@ -244,7 +229,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -256,7 +241,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 6); - return done(); + done(); }); }); @@ -268,7 +253,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -280,7 +265,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -292,15 +277,15 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); assert.equal(stats.size, 0); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file4'); fs.lstat(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -310,44 +295,44 @@ describe('asar package', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = 'a.asar'; var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a normal file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'file1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a normal directory', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'dir1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a linked file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, 'a.asar', 'file1')); + assert.equal(r, path.join(parent, 'a.asar', 'file1')); }); it('returns real path of a linked directory', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link2'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, 'a.asar', 'dir1')); + assert.equal(r, path.join(parent, 'a.asar', 'dir1')); }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); var throws = function() { - return fs.realpathSync(path.join(parent, p)); + fs.realpathSync(path.join(parent, p)); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); @@ -355,58 +340,58 @@ describe('asar package', function() { it('returns real path root', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = 'a.asar'; - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a normal file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'file1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a normal directory', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'dir1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a linked file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'file1')); - return done(); + done(); }); }); it('returns real path of a linked directory', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link2'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'dir1')); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); - return fs.realpath(path.join(parent, p), function(err) { + fs.realpath(path.join(parent, p), function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -414,27 +399,27 @@ describe('asar package', function() { it('reads dirs from root', function() { var p = path.join(fixtures, 'asar', 'a.asar'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); + assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); }); it('reads dirs from a normal dir', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); it('reads dirs from a linked dir', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); var throws = function() { - return fs.readdirSync(p); + fs.readdirSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); @@ -444,7 +429,7 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); - return done(); + done(); }); }); @@ -453,7 +438,7 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - return done(); + done(); }); }); it('reads dirs from a linked dir', function(done) { @@ -461,15 +446,15 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.readdir(p, function(err) { + fs.readdir(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -478,7 +463,6 @@ describe('asar package', function() { it('opens a normal/linked/under-linked-directory file', function() { var buffer, fd, file, j, len, p, ref2, results; ref2 = ['file1', 'link1', path.join('link2', 'file1')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -486,59 +470,57 @@ describe('asar package', function() { buffer = new Buffer(6); fs.readSync(fd, buffer, 0, 6, 0); assert.equal(String(buffer).trim(), 'file1'); - results.push(fs.closeSync(fd)); + fs.closeSync(fd); } - return results; }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); var throws = function() { - return fs.openSync(p); + fs.openSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); describe('fs.open', function() { it('opens a normal file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - return fs.open(p, 'r', function(err, fd) { - var buffer; + fs.open(p, 'r', function(err, fd) { assert.equal(err, null); - buffer = new Buffer(6); - return fs.read(fd, buffer, 0, 6, 0, function(err) { + var buffer = new Buffer(6); + fs.read(fd, buffer, 0, 6, 0, function(err) { assert.equal(err, null); assert.equal(String(buffer).trim(), 'file1'); - return fs.close(fd, done); + fs.close(fd, done); }); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.open(p, 'r', function(err) { + fs.open(p, 'r', function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); describe('fs.mkdir', function() { - return it('throws error when calling inside asar archive', function(done) { + it('throws error when calling inside asar archive', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.mkdir(p, function(err) { + fs.mkdir(p, function(err) { assert.equal(err.code, 'ENOTDIR'); - return done(); + done(); }); }); }); describe('fs.mkdirSync', function() { - return it('throws error when calling inside asar archive', function() { + it('throws error when calling inside asar archive', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return assert.throws((function() { - return fs.mkdirSync(p); + assert.throws((function() { + fs.mkdirSync(p); }), new RegExp('ENOTDIR')); }); }); @@ -548,19 +530,19 @@ describe('asar package', function() { var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); - return it('supports asar in the forked js', function(done) { + it('supports asar in the forked js', function(done) { var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); child.on('message', function(content) { assert.equal(content, fs.readFileSync(file).toString()); - return done(); + done(); }); - return child.send(file); + child.send(file); }); }); @@ -576,14 +558,13 @@ describe('asar package', function() { execFile(echo, ['test'], function(error, stdout) { assert.equal(error, null); assert.equal(stdout, 'test\n'); - return done(); + done(); }); }); - return xit('execFileSync executes binaries', function() { - var output; - output = execFileSync(echo, ['test']); - return assert.equal(String(output), 'test\n'); + xit('execFileSync executes binaries', function() { + var output = execFileSync(echo, ['test']); + assert.equal(String(output), 'test\n'); }); }); @@ -591,47 +572,45 @@ describe('asar package', function() { var internalModuleReadFile = process.binding('fs').internalModuleReadFile; it('read a normal file', function() { - var file1, file2, file3; - file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); assert.equal(internalModuleReadFile(file1).toString().trim(), 'file1'); - file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); assert.equal(internalModuleReadFile(file2).toString().trim(), 'file2'); - file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - return assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); + assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); }); - return it('reads a normal file with unpacked files', function() { - var p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); + it('reads a normal file with unpacked files', function() { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); + assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); }); }); - return describe('process.noAsar', function() { + describe('process.noAsar', function() { var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; beforeEach(function() { - return process.noAsar = true; + process.noAsar = true; }); afterEach(function() { - return process.noAsar = false; + process.noAsar = false; }); it('disables asar support in sync API', function() { var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); assert.throws((function() { - return fs.readFileSync(file); + fs.readFileSync(file); }), new RegExp(errorName)); assert.throws((function() { - return fs.lstatSync(file); + fs.lstatSync(file); }), new RegExp(errorName)); assert.throws((function() { - return fs.realpathSync(file); + fs.realpathSync(file); }), new RegExp(errorName)); - return assert.throws((function() { - return fs.readdirSync(dir); + assert.throws((function() { + fs.readdirSync(dir); }), new RegExp(errorName)); }); @@ -639,30 +618,29 @@ describe('asar package', function() { var dir, file; file = path.join(fixtures, 'asar', 'a.asar', 'file1'); dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - return fs.readFile(file, function(error) { + fs.readFile(file, function(error) { assert.equal(error.code, errorName); - return fs.lstat(file, function(error) { + fs.lstat(file, function(error) { assert.equal(error.code, errorName); - return fs.realpath(file, function(error) { + fs.realpath(file, function(error) { assert.equal(error.code, errorName); - return fs.readdir(dir, function(error) { + fs.readdir(dir, function(error) { assert.equal(error.code, errorName); - return done(); + done(); }); }); }); }); }); - return it('treats *.asar as normal file', function() { - var asar, content1, content2, originalFs; - originalFs = require('original-fs'); - asar = path.join(fixtures, 'asar', 'a.asar'); - content1 = fs.readFileSync(asar); - content2 = originalFs.readFileSync(asar); + it('treats *.asar as normal file', function() { + var originalFs = require('original-fs'); + var asar = path.join(fixtures, 'asar', 'a.asar'); + var content1 = fs.readFileSync(asar); + var content2 = originalFs.readFileSync(asar); assert.equal(content1.compare(content2), 0); - return assert.throws((function() { - return fs.readdirSync(asar); + assert.throws((function() { + fs.readdirSync(asar); }), /ENOTDIR/); }); }); @@ -673,43 +651,43 @@ describe('asar package', function() { it('can request a file in package', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); - return done(); + done(); }); }); it('can request a file in package with unpacked files', function(done) { var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'a'); - return done(); + done(); }); }); it('can request a linked file in package', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); - return done(); + done(); }); }); it('can request a file in filesystem', function(done) { var p = path.resolve(fixtures, 'asar', 'file'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file'); - return done(); + done(); }); }); it('gets 404 when file is not found', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); - return $.ajax({ + $.ajax({ url: "file://" + p, error: function(err) { assert.equal(err.status, 404); - return done(); + done(); } }); }); @@ -717,7 +695,7 @@ describe('asar package', function() { it('sets __dirname correctly', function(done) { after(function() { w.destroy(); - return ipcMain.removeAllListeners('dirname'); + ipcMain.removeAllListeners('dirname'); }); var w = new BrowserWindow({ @@ -733,15 +711,15 @@ describe('asar package', function() { }); ipcMain.once('dirname', function(event, dirname) { assert.equal(dirname, path.dirname(p)); - return done(); + done(); }); - return w.loadURL(u); + w.loadURL(u); }); - return it('loads script tag in html', function(done) { + it('loads script tag in html', function(done) { after(function() { w.destroy(); - return ipcMain.removeAllListeners('ping'); + ipcMain.removeAllListeners('ping'); }); var w = new BrowserWindow({ @@ -756,9 +734,9 @@ describe('asar package', function() { pathname: p }); w.loadURL(u); - return ipcMain.once('ping', function(event, message) { + ipcMain.once('ping', function(event, message) { assert.equal(message, 'pong'); - return done(); + done(); }); }); }); @@ -770,17 +748,17 @@ describe('asar package', function() { var file, stats; file = path.join(fixtures, 'asar', 'a.asar'); stats = originalFs.statSync(file); - return assert(stats.isFile()); + assert(stats.isFile()); }); - return it('is available in forked scripts', function(done) { + it('is available in forked scripts', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); child.on('message', function(msg) { assert.equal(msg, 'object'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); }); @@ -788,41 +766,39 @@ describe('asar package', function() { var gfs = require('graceful-fs'); it('recognize asar archvies', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return assert.equal(gfs.readFileSync(p).toString().trim(), 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + assert.equal(gfs.readFileSync(p).toString().trim(), 'file1'); }); - return it('does not touch global fs object', function() { - return assert.notEqual(fs.readdir, gfs.readdir); + it('does not touch global fs object', function() { + assert.notEqual(fs.readdir, gfs.readdir); }); }); describe('mkdirp module', function() { var mkdirp = require('mkdirp'); - return it('throws error when calling inside asar archive', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return assert.throws((function() { - return mkdirp.sync(p); + it('throws error when calling inside asar archive', function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + assert.throws((function() { + mkdirp.sync(p); }), new RegExp('ENOTDIR')); }); }); - return describe('native-image', function() { + describe('native-image', function() { it('reads image from asar archive', function() { var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); var logo = nativeImage.createFromPath(p); - return assert.deepEqual(logo.getSize(), { + assert.deepEqual(logo.getSize(), { width: 55, height: 55 }); }); - return it('reads image from asar archive with unpacked files', function() { + it('reads image from asar archive with unpacked files', function() { var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); var logo = nativeImage.createFromPath(p); - return assert.deepEqual(logo.getSize(), { + assert.deepEqual(logo.getSize(), { width: 1024, height: 1024 }); diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 21cefb0b0bcb..9efe22a263c8 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -15,28 +15,27 @@ describe('chromium feature', function() { if (listener != null) { window.removeEventListener('message', listener); } - return listener = null; + listener = null; }); xdescribe('heap snapshot', function() { - return it('does not crash', function() { - return process.atomBinding('v8_util').takeHeapSnapshot(); + it('does not crash', function() { + process.atomBinding('v8_util').takeHeapSnapshot(); }); }); describe('sending request of http protocol urls', function() { - return it('does not crash', function(done) { - var server; + it('does not crash', function(done) { this.timeout(5000); - server = http.createServer(function(req, res) { + + var server = http.createServer(function(req, res) { res.end(); server.close(); - return done(); + done(); }); - return server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; - return $.get("http://127.0.0.1:" + port); + server.listen(0, '127.0.0.1', function() { + var port = server.address().port; + $.get("http://127.0.0.1:" + port); }); }); }); @@ -46,7 +45,7 @@ describe('chromium feature', function() { var w = null; afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); it('is set correctly when window is not shown', function(done) { @@ -55,41 +54,42 @@ describe('chromium feature', function() { }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['hidden', true]); - return done(); + done(); }); - return w.loadURL(url); + w.loadURL(url); }); - return it('is set correctly when window is inactive', function(done) { + it('is set correctly when window is inactive', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['hidden', false]); - return done(); + done(); }); w.showInactive(); - return w.loadURL(url); + w.loadURL(url); }); }); xdescribe('navigator.webkitGetUserMedia', function() { - return it('calls its callbacks', function(done) { + it('calls its callbacks', function(done) { this.timeout(5000); - return navigator.webkitGetUserMedia({ + + navigator.webkitGetUserMedia({ audio: true, video: false }, function() { - return done(); + done(); }, function() { - return done(); + done(); }); }); }); describe('navigator.language', function() { - return it('should not be empty', function() { - return assert.notEqual(navigator.language, ''); + it('should not be empty', function() { + assert.notEqual(navigator.language, ''); }); }); @@ -98,28 +98,28 @@ describe('chromium feature', function() { var w = null; afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); - return it('should register for file scheme', function(done) { + it('should register for file scheme', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { if (args[0] === 'reload') { - return w.webContents.reload(); + w.webContents.reload(); } else if (args[0] === 'error') { - return done('unexpected error : ' + args[1]); + done('unexpected error : ' + args[1]); } else if (args[0] === 'response') { assert.equal(args[1], 'Hello from serviceWorker!'); - return session.defaultSession.clearStorageData({ + session.defaultSession.clearStorageData({ storages: ['serviceworkers'] }, function() { - return done(); + done(); }); } }); - return w.loadURL(url); + sw.loadURL(url); }); }); @@ -127,11 +127,10 @@ describe('chromium feature', function() { this.timeout(20000); it('returns a BrowserWindowProxy object', function() { - var b; - b = window.open('about:blank', '', 'show=no'); + var b = window.open('about:blank', '', 'show=no'); assert.equal(b.closed, false); assert.equal(b.constructor.name, 'BrowserWindowProxy'); - return b.close(); + b.close(); }); it('accepts "node-integration" as feature', function(done) { @@ -139,10 +138,10 @@ describe('chromium feature', function() { listener = function(event) { assert.equal(event.data, 'undefined'); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); + b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); }); it('inherit options of parent window', function(done) { @@ -152,13 +151,13 @@ describe('chromium feature', function() { ref1 = remote.getCurrentWindow().getSize(), width = ref1[0], height = ref1[1]; assert.equal(event.data, "size: " + width + " " + height); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); + b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); }); - return it('does not override child options', function(done) { + it('does not override child options', function(done) { var b, size; size = { width: 350, @@ -167,45 +166,48 @@ describe('chromium feature', function() { listener = function(event) { assert.equal(event.data, "size: " + size.width + " " + size.height); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); + b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); }); }); describe('window.opener', function() { - var url, w; this.timeout(10000); - url = "file://" + fixtures + "/pages/window-opener.html"; - w = null; + + var url = "file://" + fixtures + "/pages/window-opener.html"; + var w = null; + afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); + it('is null for main window', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['opener', null]); - return done(); + done(); }); - return w.loadURL(url); + w.loadURL(url); }); - return it('is not null for window opened by window.open', function(done) { + + it('is not null for window opened by window.open', function(done) { var b; listener = function(event) { assert.equal(event.data, 'object'); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open(url, '', 'show=no'); + b = window.open(url, '', 'show=no'); }); }); describe('window.postMessage', function() { - return it('sets the source and origin correctly', function(done) { + it('sets the source and origin correctly', function(done) { var b, sourceId; sourceId = remote.getCurrentWindow().id; listener = function(event) { @@ -218,47 +220,47 @@ describe('chromium feature', function() { assert.equal(message.sourceEqualsOpener, true); assert.equal(message.sourceId, sourceId); assert.equal(event.origin, 'file://'); - return done(); + done(); }; window.addEventListener('message', listener); b = window.open("file://" + fixtures + "/pages/window-open-postMessage.html", '', 'show=no'); - return BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { - return b.postMessage('testing', '*'); + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + b.postMessage('testing', '*'); }); }); }); describe('window.opener.postMessage', function() { - return it('sets source and origin correctly', function(done) { + it('sets source and origin correctly', function(done) { var b; listener = function(event) { window.removeEventListener('message', listener); b.close(); assert.equal(event.source, b); assert.equal(event.origin, 'file://'); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); + b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); }); }); describe('creating a Uint8Array under browser side', function() { - return it('does not crash', function() { + it('does not crash', function() { var RUint8Array; RUint8Array = remote.getGlobal('Uint8Array'); - return new RUint8Array; + new RUint8Array; }); }); describe('webgl', function() { - return it('can be get as context in canvas', function() { + it('can be get as context in canvas', function() { var webgl; if (process.platform === 'linux') { return; } webgl = document.createElement('canvas').getContext('webgl'); - return assert.notEqual(webgl, null); + assert.notEqual(webgl, null); }); }); @@ -270,20 +272,20 @@ describe('chromium feature', function() { worker.onmessage = function(event) { assert.equal(event.data, message); worker.terminate(); - return done(); + done(); }; - return worker.postMessage(message); + worker.postMessage(message); }); - return it('SharedWorker can work', function(done) { + it('SharedWorker can work', function(done) { var message, worker; worker = new SharedWorker('../fixtures/workers/shared_worker.js'); message = 'ping'; worker.port.onmessage = function(event) { assert.equal(event.data, message); - return done(); + done(); }; - return worker.port.postMessage(message); + worker.port.postMessage(message); }); }); @@ -291,28 +293,28 @@ describe('chromium feature', function() { var iframe = null; beforeEach(function() { - return iframe = document.createElement('iframe'); + iframe = document.createElement('iframe'); }); afterEach(function() { - return document.body.removeChild(iframe); + document.body.removeChild(iframe); }); - return it('does not have node integration', function(done) { + it('does not have node integration', function(done) { iframe.src = "file://" + fixtures + "/pages/set-global.html"; document.body.appendChild(iframe); - return iframe.onload = function() { + iframe.onload = function() { assert.equal(iframe.contentWindow.test, 'undefined undefined undefined'); - return done(); + done(); }; }); }); describe('storage', function() { - return it('requesting persitent quota works', function(done) { - return navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { + it('requesting persitent quota works', function(done) { + navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { assert.equal(grantedBytes, 1048576); - return done(); + done(); }); }); }); @@ -324,12 +326,12 @@ describe('chromium feature', function() { afterEach(function() { wss.close(); - return server.close(); + server.close(); }); - return it('has user agent', function(done) { + it('has user agent', function(done) { server = http.createServer(); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; wss = new WebSocketServer({ server: server @@ -337,9 +339,9 @@ describe('chromium feature', function() { wss.on('error', done); wss.on('connection', function(ws) { if (ws.upgradeReq.headers['user-agent']) { - return done(); + done(); } else { - return done('user agent is empty'); + done('user agent is empty'); } }); new WebSocket("ws://127.0.0.1:" + port); @@ -347,7 +349,7 @@ describe('chromium feature', function() { }); }); - return describe('Promise', function() { + describe('Promise', function() { it('resolves correctly in Node.js calls', function(done) { document.registerElement('x-element', { prototype: Object.create(HTMLElement.prototype, { @@ -356,18 +358,17 @@ describe('chromium feature', function() { } }) }); - return setImmediate(function() { - var called; - called = false; + setImmediate(function() { + var called = false; Promise.resolve().then(function() { - return done(called ? void 0 : new Error('wrong sequence')); + done(called ? void 0 : new Error('wrong sequence')); }); document.createElement('x-element'); - return called = true; + called = true; }); }); - return it('resolves correctly in Electron calls', function(done) { + it('resolves correctly in Electron calls', function(done) { document.registerElement('y-element', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { @@ -375,14 +376,14 @@ describe('chromium feature', function() { } }) }); - return remote.getGlobal('setImmediate')(function() { + remote.getGlobal('setImmediate')(function() { var called; called = false; Promise.resolve().then(function() { - return done(called ? void 0 : new Error('wrong sequence')); + done(called ? void 0 : new Error('wrong sequence')); }); document.createElement('y-element'); - return called = true; + called = true; }); }); }); diff --git a/spec/modules-spec.js b/spec/modules-spec.js index e3d5bd75c6d8..fb53a90cf735 100644 --- a/spec/modules-spec.js +++ b/spec/modules-spec.js @@ -9,40 +9,37 @@ describe('third-party module', function() { if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { describe('runas', function() { it('can be required in renderer', function() { - return require('runas'); + require('runas'); }); - return it('can be required in node binary', function(done) { - var child, runas; - runas = path.join(fixtures, 'module', 'runas.js'); - child = require('child_process').fork(runas); - return child.on('message', function(msg) { + it('can be required in node binary', function(done) { + var runas = path.join(fixtures, 'module', 'runas.js'); + var child = require('child_process').fork(runas); + child.on('message', function(msg) { assert.equal(msg, 'ok'); - return done(); + done(); }); }); }); describe('ffi', function() { - return it('does not crash', function() { - var ffi, libm; - ffi = require('ffi'); - libm = ffi.Library('libm', { + it('does not crash', function() { + var ffi = require('ffi'); + var libm = ffi.Library('libm', { ceil: ['double', ['double']] }); - return assert.equal(libm.ceil(1.5), 2); + assert.equal(libm.ceil(1.5), 2); }); }); } - return describe('q', function() { - var Q; - Q = require('q'); - return describe('Q.when', function() { - return it('emits the fullfil callback', function(done) { - return Q(true).then(function(val) { + describe('q', function() { + var Q = require('q'); + describe('Q.when', function() { + it('emits the fullfil callback', function(done) { + Q(true).then(function(val) { assert.equal(val, true); - return done(); + done(); }); }); }); diff --git a/spec/node-spec.js b/spec/node-spec.js index 9ead92026539..2961b14b02b5 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -9,48 +9,45 @@ describe('node feature', function() { var fixtures = path.join(__dirname, 'fixtures'); describe('child_process', function() { - return describe('child_process.fork', function() { + describe('child_process.fork', function() { it('works in current process', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('preserves args', function(done) { - var args, child; - args = ['--expose_gc', '-test', '1']; - child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args); + var args = ['--expose_gc', '-test', '1']; + var child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args); child.on('message', function(msg) { assert.deepEqual(args, msg.slice(2)); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in forked process', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in forked process when options.env is specifed', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { + var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { path: process.env['PATH'] }); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in browser process', function(done) { @@ -59,9 +56,9 @@ describe('node feature', function() { child = fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('has String::localeCompare working in script', function(done) { @@ -69,19 +66,18 @@ describe('node feature', function() { child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); child.on('message', function(msg) { assert.deepEqual(msg, [0, -1, 1]); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); - return it('has setImmediate working in script', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); + it('has setImmediate working in script', function(done) { + var child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); child.on('message', function(msg) { assert.equal(msg, 'ok'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); }); }); @@ -92,18 +88,17 @@ describe('node feature', function() { return; } - return it('does not crash', function(done) { - return fs.readFile(__filename, function() { - return setTimeout(done, 0); + it('does not crash', function(done) { + fs.readFile(__filename, function() { + setTimeout(done, 0); }); }); }); describe('throw error in node context', function() { - return it('gets caught', function(done) { - var error, lsts; - error = new Error('boo!'); - lsts = process.listeners('uncaughtException'); + it('gets caught', function(done) { + var error = new Error('boo!'); + var lsts = process.listeners('uncaughtException'); process.removeAllListeners('uncaughtException'); process.on('uncaughtException', function() { var i, len, lst; @@ -112,28 +107,28 @@ describe('node feature', function() { lst = lsts[i]; process.on('uncaughtException', lst); } - return done(); + done(); }); - return fs.readFile(__filename, function() { + fs.readFile(__filename, function() { throw error; }); }); }); describe('setTimeout called under Chromium event loop in browser process', function() { - return it('can be scheduled in time', function(done) { - return remote.getGlobal('setTimeout')(done, 0); + it('can be scheduled in time', function(done) { + remote.getGlobal('setTimeout')(done, 0); }); }); - return describe('setInterval called under Chromium event loop in browser process', function() { - return it('can be scheduled in time', function(done) { + describe('setInterval called under Chromium event loop in browser process', function() { + it('can be scheduled in time', function(done) { var clear, interval; clear = function() { remote.getGlobal('clearInterval')(interval); - return done(); + done(); }; - return interval = remote.getGlobal('setInterval')(clear, 10); + interval = remote.getGlobal('setInterval')(clear, 10); }); }); }); @@ -141,27 +136,27 @@ describe('node feature', function() { describe('message loop', function() { describe('process.nextTick', function() { it('emits the callback', function(done) { - return process.nextTick(done); + process.nextTick(done); }); - return it('works in nested calls', function(done) { - return process.nextTick(function() { - return process.nextTick(function() { - return process.nextTick(done); + it('works in nested calls', function(done) { + process.nextTick(function() { + process.nextTick(function() { + process.nextTick(done); }); }); }); }); - return describe('setImmediate', function() { + describe('setImmediate', function() { it('emits the callback', function(done) { - return setImmediate(done); + setImmediate(done); }); - return it('works in nested calls', function(done) { - return setImmediate(function() { - return setImmediate(function() { - return setImmediate(done); + it('works in nested calls', function(done) { + setImmediate(function() { + setImmediate(function() { + setImmediate(done); }); }); }); @@ -173,18 +168,18 @@ describe('node feature', function() { return; } - return it('emit error when connect to a socket path without listeners', function(done) { + it('emit error when connect to a socket path without listeners', function(done) { var child, script, socketPath; socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); script = path.join(fixtures, 'module', 'create_socket.js'); child = child_process.fork(script, [socketPath]); - return child.on('exit', function(code) { + child.on('exit', function(code) { var client; assert.equal(code, 0); client = require('net').connect(socketPath); - return client.on('error', function(error) { + client.on('error', function(error) { assert.equal(error.code, 'ECONNREFUSED'); - return done(); + done(); }); }); }); @@ -197,16 +192,16 @@ describe('node feature', function() { p.innerText = '闲云潭影日悠悠,物换星移几度秋'; b = new Buffer(p.innerText); assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); - return assert.equal(Buffer.byteLength(p.innerText), 45); + assert.equal(Buffer.byteLength(p.innerText), 45); }); - return it('correctly parses external one-byte UTF8 string', function() { + it('correctly parses external one-byte UTF8 string', function() { var b, p; p = document.createElement('p'); p.innerText = 'Jøhänñéß'; b = new Buffer(p.innerText); assert.equal(b.toString(), 'Jøhänñéß'); - return assert.equal(Buffer.byteLength(p.innerText), 13); + assert.equal(Buffer.byteLength(p.innerText), 13); }); }); From 8a9395101e259e6cc16142793654bab16824362c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:45:18 -0800 Subject: [PATCH 074/132] Remove unused results --- spec/api-menu-spec.js | 4 ++-- spec/asar-spec.js | 26 +++++++++----------------- spec/chromium-spec.js | 2 +- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 60464c732754..b27840ec4f2e 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -271,7 +271,7 @@ describe('menu module', function() { }); it('should assign groupId automatically', function() { - var groupId, i, j, k, l, m, menu, results, template; + var groupId, i, j, k, l, m, menu, template; template = []; for (i = j = 0; j <= 10; i = ++j) { template.push({ @@ -299,7 +299,7 @@ describe('menu module', function() { }); it("setting 'checked' should flip other items' 'checked' property", function() { - var i, j, k, l, m, menu, n, o, p, q, results, template; + var i, j, k, l, m, menu, n, o, p, q, template; template = []; for (i = j = 0; j <= 10; i = ++j) { template.push({ diff --git a/spec/asar-spec.js b/spec/asar-spec.js index d35cf186c65a..3bdff95ae3dc 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -138,9 +138,8 @@ describe('asar package', function() { }); it('returns information of a normal file', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -148,15 +147,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), true); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), false); - results.push(assert.equal(stats.size, 6)); + assert.equal(stats.size, 6); } - results; }); it('returns information of a normal directory', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['dir1', 'dir2', 'dir3']; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -164,15 +161,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('returns information of a linked file', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -180,15 +175,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('returns information of a linked directory', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -196,9 +189,8 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('throws ENOENT error when can not find file', function() { @@ -461,7 +453,7 @@ describe('asar package', function() { describe('fs.openSync', function() { it('opens a normal/linked/under-linked-directory file', function() { - var buffer, fd, file, j, len, p, ref2, results; + var buffer, fd, file, j, len, p, ref2; ref2 = ['file1', 'link1', path.join('link2', 'file1')]; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 9efe22a263c8..4b894b4bbc85 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -119,7 +119,7 @@ describe('chromium feature', function() { }); } }); - sw.loadURL(url); + w.loadURL(url); }); }); From 54d7c580bdca5091bf5749058a16f1591bfcc34c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:46:44 -0800 Subject: [PATCH 075/132] Remove unneeded returns --- spec/api-protocol-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index a7de60d8c36b..215868bfdc8a 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -122,7 +122,7 @@ describe('protocol module', function() { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); @@ -310,7 +310,7 @@ describe('protocol module', function() { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(fileContent)); @@ -325,7 +325,7 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(filePath); + callback(filePath); }; protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { @@ -346,7 +346,7 @@ describe('protocol module', function() { }); it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ path: filePath }); }; @@ -440,7 +440,7 @@ describe('protocol module', function() { res.end(text); server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; var url = "http://127.0.0.1:" + port; var handler = function(request, callback) { @@ -586,7 +586,7 @@ describe('protocol module', function() { var doubleHandler = function(request, callback) { try { callback(text); - return callback(); + callback(); } catch (error) { // Ignore error } From 31028ab6366654d1b52d387d14054a5bd8e7c5bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:27:25 -0800 Subject: [PATCH 076/132] Update var declarations --- spec/api-app-spec.js | 7 +- spec/api-browser-window-spec.js | 57 ++++++--------- spec/api-crash-reporter-spec.js | 3 +- spec/api-ipc-spec.js | 10 ++- spec/api-session-spec.js | 9 +-- spec/api-web-request-spec.js | 12 ++-- spec/asar-spec.js | 18 ++--- spec/chromium-spec.js | 22 +++--- spec/node-spec.js | 31 ++++---- spec/webview-spec.js | 122 ++++++++++++-------------------- 10 files changed, 110 insertions(+), 181 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 7b2535d54041..cbf8223401ce 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -66,11 +66,10 @@ describe('app module', function() { }); it('emits a process exit event with the code', function(done) { - var appPath, electronPath, output; - appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); - electronPath = remote.getGlobal('process').execPath; + var appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); + var electronPath = remote.getGlobal('process').execPath; + var output = ''; appProcess = ChildProcess.spawn(electronPath, [appPath]); - output = ''; appProcess.stdout.on('data', function(data) { output += data; }); diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index b64ef6145b78..58cf57cc8d0c 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -42,9 +42,8 @@ describe('browser-window module', function() { w.close(); }); w.on('closed', function() { - var content, test; - test = path.join(fixtures, 'api', 'unload'); - content = fs.readFileSync(test); + var test = path.join(fixtures, 'api', 'unload'); + var content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'unload'); done(); @@ -66,9 +65,8 @@ describe('browser-window module', function() { describe('window.close()', function() { it('should emit unload handler', function(done) { w.on('closed', function() { - var content, test; - test = path.join(fixtures, 'api', 'close'); - content = fs.readFileSync(test); + var test = path.join(fixtures, 'api', 'close'); + var content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'close'); done(); @@ -86,8 +84,7 @@ describe('browser-window module', function() { describe('BrowserWindow.destroy()', function() { it('prevents users to access methods of webContents', function() { - var webContents; - webContents = w.webContents; + var webContents = w.webContents; w.destroy(); assert.throws((function() { webContents.getId(); @@ -178,8 +175,7 @@ describe('browser-window module', function() { it('sets the window position', function(done) { var pos = [10, 10]; w.once('move', function() { - var newPos; - newPos = w.getPosition(); + var newPos = w.getPosition(); assert.equal(newPos[0], pos[0]); assert.equal(newPos[1], pos[1]); done(); @@ -190,16 +186,14 @@ describe('browser-window module', function() { describe('BrowserWindow.setContentSize(width, height)', function() { it('sets the content size', function() { - var after, size; - size = [400, 400]; + var size = [400, 400]; w.setContentSize(size[0], size[1]); - after = w.getContentSize(); + var after = w.getContentSize(); assert.equal(after[0], size[0]); assert.equal(after[1], size[1]); }); it('works for framless window', function() { - var after, size; w.destroy(); w = new BrowserWindow({ show: false, @@ -207,9 +201,9 @@ describe('browser-window module', function() { width: 400, height: 400 }); - size = [400, 400]; + var size = [400, 400]; w.setContentSize(size[0], size[1]); - after = w.getContentSize(); + var after = w.getContentSize(); assert.equal(after[0], size[0]); assert.equal(after[1], size[1]); }); @@ -223,7 +217,6 @@ describe('browser-window module', function() { describe('"useContentSize" option', function() { it('make window created with content size when used', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -231,7 +224,7 @@ describe('browser-window module', function() { height: 400, useContentSize: true }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[0], 400); assert.equal(contentSize[1], 400); }); @@ -243,7 +236,6 @@ describe('browser-window module', function() { }); it('works for framless window', function() { - var contentSize, size; w.destroy(); w = new BrowserWindow({ show: false, @@ -252,10 +244,10 @@ describe('browser-window module', function() { height: 400, useContentSize: true }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[0], 400); assert.equal(contentSize[1], 400); - size = w.getSize(); + var size = w.getSize(); assert.equal(size[0], 400); assert.equal(size[1], 400); }); @@ -270,7 +262,6 @@ describe('browser-window module', function() { } it('creates browser window with hidden title bar', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -278,12 +269,11 @@ describe('browser-window module', function() { height: 400, titleBarStyle: 'hidden' }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[1], 400); }); it('creates browser window with hidden inset title bar', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -291,7 +281,7 @@ describe('browser-window module', function() { height: 400, titleBarStyle: 'hidden-inset' }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[1], 400); }); }); @@ -312,20 +302,18 @@ describe('browser-window module', function() { }); it('can move the window out of screen', function() { - var after; w.setPosition(-10, -10); - after = w.getPosition(); + var after = w.getPosition(); assert.equal(after[0], -10); assert.equal(after[1], -10); }); it('can set the window larger than screen', function() { - var after, size; - size = screen.getPrimaryDisplay().size; + var size = screen.getPrimaryDisplay().size; size.width += 100; size.height += 100; w.setSize(size.width, size.height); - after = w.getSize(); + var after = w.getSize(); assert.equal(after[0], size.width); assert.equal(after[1], size.height); }); @@ -338,8 +326,7 @@ describe('browser-window module', function() { describe('"preload" option', function() { it('loads the script before other scripts in window', function(done) { - var preload; - preload = path.join(fixtures, 'module', 'set-global.js'); + var preload = path.join(fixtures, 'module', 'set-global.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'preload'); done(); @@ -357,8 +344,7 @@ describe('browser-window module', function() { describe('"node-integration" option', function() { it('disables node integration when specified to false', function(done) { - var preload; - preload = path.join(fixtures, 'module', 'send-later.js'); + var preload = path.join(fixtures, 'module', 'send-later.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'undefined'); done(); @@ -532,10 +518,9 @@ describe('browser-window module', function() { describe('BrowserWindow options argument is optional', function() { it('should create a window with default size (800x600)', function() { - var size; w.destroy(); w = new BrowserWindow(); - size = w.getSize(); + var size = w.getSize(); assert.equal(size[0], 800); assert.equal(size[1], 600); }); diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 43830dd4ee16..68dc1375fc39 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -37,9 +37,8 @@ describe('crash-reporter module', function() { var called = false; var server = http.createServer(function(req, res) { - var form; server.close(); - form = new multiparty.Form(); + var form = new multiparty.Form(); form.parse(req, function(error, fields) { if (called) { return; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 25d8c925688f..2c8bc28f1560 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -20,9 +20,8 @@ describe('ipc module', function() { describe('remote.require', function() { it('should returns same object for the same module', function() { - var dialog1, dialog2; - dialog1 = remote.require('electron'); - dialog2 = remote.require('electron'); + var dialog1 = remote.require('electron'); + var dialog2 = remote.require('electron'); assert.equal(dialog1, dialog2); }); @@ -58,9 +57,8 @@ describe('ipc module', function() { }); it('can construct an object from its member', function() { - var call, obj; - call = remote.require(path.join(fixtures, 'module', 'call.js')); - obj = new call.constructor; + var call = remote.require(path.join(fixtures, 'module', 'call.js')); + var obj = new call.constructor; assert.equal(obj.test, 'test'); }); }); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 049309eda589..9fedcc29e779 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -31,15 +31,13 @@ describe('session module', function() { describe('session.cookies', function() { it('should get cookies', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { res.setHeader('Set-Cookie', ['0=0']); res.end('finished'); server.close(); }); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; w.loadURL(url + ":" + port); w.webContents.on('did-finish-load', function() { w.webContents.session.cookies.get({ @@ -136,8 +134,7 @@ describe('session module', function() { }); w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')); w.webContents.on('did-finish-load', function() { - var options; - options = { + var options = { origin: "file://", storages: ['localstorage'], quotas: ['persistent'] diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index f64c91b610c5..77f160a20041 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -7,9 +7,8 @@ const session = remote.session; describe('webRequest module', function() { var ses = session.defaultSession; var server = http.createServer(function(req, res) { - var content; res.setHeader('Custom', ['Header']); - content = req.url; + var content = req.url; if (req.headers.accept === '*/*;test/header') { content += 'header/received'; } @@ -19,8 +18,7 @@ describe('webRequest module', function() { before(function(done) { server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; defaultURL = "http://127.0.0.1:" + port + "/"; done(); }); @@ -109,11 +107,10 @@ describe('webRequest module', function() { type: 'string' }; ses.webRequest.onBeforeRequest(function(details, callback) { - var data; assert.equal(details.url, defaultURL); assert.equal(details.method, 'POST'); assert.equal(details.uploadData.length, 1); - data = qs.parse(details.uploadData[0].bytes.toString()); + var data = qs.parse(details.uploadData[0].bytes.toString()); assert.deepEqual(data, postData); callback({ cancel: true @@ -178,8 +175,7 @@ describe('webRequest module', function() { it('can change the request headers', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { - var requestHeaders; - requestHeaders = details.requestHeaders; + var requestHeaders = details.requestHeaders; requestHeaders.Accept = '*/*;test/header'; callback({ requestHeaders: requestHeaders diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 3bdff95ae3dc..060074390f1b 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -128,9 +128,8 @@ describe('asar package', function() { }); it('returns information of root', function() { - var p, stats; - p = path.join(fixtures, 'asar', 'a.asar'); - stats = fs.lstatSync(p); + var p = path.join(fixtures, 'asar', 'a.asar'); + var stats = fs.lstatSync(p); assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); @@ -607,9 +606,8 @@ describe('asar package', function() { }); it('disables asar support in async API', function(done) { - var dir, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.readFile(file, function(error) { assert.equal(error.code, errorName); fs.lstat(file, function(error) { @@ -737,15 +735,13 @@ describe('asar package', function() { var originalFs = require('original-fs'); it('treats .asar as file', function() { - var file, stats; - file = path.join(fixtures, 'asar', 'a.asar'); - stats = originalFs.statSync(file); + var file = path.join(fixtures, 'asar', 'a.asar'); + var stats = originalFs.statSync(file); assert(stats.isFile()); }); it('is available in forked scripts', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); child.on('message', function(msg) { assert.equal(msg, 'object'); done(); diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 4b894b4bbc85..e4444f55b11d 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -211,10 +211,9 @@ describe('chromium feature', function() { var b, sourceId; sourceId = remote.getCurrentWindow().id; listener = function(event) { - var message; window.removeEventListener('message', listener); b.close(); - message = JSON.parse(event.data); + var message = JSON.parse(event.data); assert.equal(message.data, 'testing'); assert.equal(message.origin, 'file://'); assert.equal(message.sourceEqualsOpener, true); @@ -247,28 +246,25 @@ describe('chromium feature', function() { describe('creating a Uint8Array under browser side', function() { it('does not crash', function() { - var RUint8Array; - RUint8Array = remote.getGlobal('Uint8Array'); + var RUint8Array = remote.getGlobal('Uint8Array'); new RUint8Array; }); }); describe('webgl', function() { it('can be get as context in canvas', function() { - var webgl; if (process.platform === 'linux') { return; } - webgl = document.createElement('canvas').getContext('webgl'); + var webgl = document.createElement('canvas').getContext('webgl'); assert.notEqual(webgl, null); }); }); describe('web workers', function() { it('Worker can work', function(done) { - var message, worker; - worker = new Worker('../fixtures/workers/worker.js'); - message = 'ping'; + var worker = new Worker('../fixtures/workers/worker.js'); + var message = 'ping'; worker.onmessage = function(event) { assert.equal(event.data, message); worker.terminate(); @@ -278,9 +274,8 @@ describe('chromium feature', function() { }); it('SharedWorker can work', function(done) { - var message, worker; - worker = new SharedWorker('../fixtures/workers/shared_worker.js'); - message = 'ping'; + var worker = new SharedWorker('../fixtures/workers/shared_worker.js'); + var message = 'ping'; worker.port.onmessage = function(event) { assert.equal(event.data, message); done(); @@ -377,8 +372,7 @@ describe('chromium feature', function() { }) }); remote.getGlobal('setImmediate')(function() { - var called; - called = false; + var called = false; Promise.resolve().then(function() { done(called ? void 0 : new Error('wrong sequence')); }); diff --git a/spec/node-spec.js b/spec/node-spec.js index 2961b14b02b5..83f685d95f04 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -11,8 +11,7 @@ describe('node feature', function() { describe('child_process', function() { describe('child_process.fork', function() { it('works in current process', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); done(); @@ -51,9 +50,8 @@ describe('node feature', function() { }); it('works in browser process', function(done) { - var child, fork; - fork = remote.require('child_process').fork; - child = fork(path.join(fixtures, 'module', 'ping.js')); + var fork = remote.require('child_process').fork; + var child = fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); done(); @@ -62,8 +60,7 @@ describe('node feature', function() { }); it('has String::localeCompare working in script', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); child.on('message', function(msg) { assert.deepEqual(msg, [0, -1, 1]); done(); @@ -169,14 +166,12 @@ describe('node feature', function() { } it('emit error when connect to a socket path without listeners', function(done) { - var child, script, socketPath; - socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); - script = path.join(fixtures, 'module', 'create_socket.js'); - child = child_process.fork(script, [socketPath]); + var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); + var script = path.join(fixtures, 'module', 'create_socket.js'); + var child = child_process.fork(script, [socketPath]); child.on('exit', function(code) { - var client; assert.equal(code, 0); - client = require('net').connect(socketPath); + var client = require('net').connect(socketPath); client.on('error', function(error) { assert.equal(error.code, 'ECONNREFUSED'); done(); @@ -187,19 +182,17 @@ describe('node feature', function() { describe('Buffer', function() { it('can be created from WebKit external string', function() { - var b, p; - p = document.createElement('p'); + var p = document.createElement('p'); p.innerText = '闲云潭影日悠悠,物换星移几度秋'; - b = new Buffer(p.innerText); + var b = new Buffer(p.innerText); assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); assert.equal(Buffer.byteLength(p.innerText), 45); }); it('correctly parses external one-byte UTF8 string', function() { - var b, p; - p = document.createElement('p'); + var p = document.createElement('p'); p.innerText = 'Jøhänñéß'; - b = new Buffer(p.innerText); + var b = new Buffer(p.innerText); assert.equal(b.toString(), 'Jøhänñéß'); assert.equal(Buffer.byteLength(p.innerText), 13); }); diff --git a/spec/webview-spec.js b/spec/webview-spec.js index a18e152ea6aa..54b544def0db 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -95,8 +95,7 @@ describe(' tag', function() { describe('preload attribute', function() { it('loads the script before other scripts in window', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'function object object'); webview.removeEventListener('console-message', listener); done(); @@ -118,15 +117,14 @@ describe(' tag', function() { }); it('receives ipc message in preload script', function(done) { - var listener, listener2, message; - message = 'boom!'; - listener = function(e) { + var message = 'boom!'; + var listener = function(e) { assert.equal(e.channel, 'pong'); assert.deepEqual(e.args, [message]); webview.removeEventListener('ipc-message', listener); done(); }; - listener2 = function() { + var listener2 = function() { webview.send('ping', message); webview.removeEventListener('did-finish-load', listener2); }; @@ -140,9 +138,8 @@ describe(' tag', function() { describe('httpreferrer attribute', function() { it('sets the referrer url', function(done) { - var listener, referrer; - referrer = 'http://github.com/'; - listener = function(e) { + var referrer = 'http://github.com/'; + var listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); done(); @@ -156,9 +153,8 @@ describe(' tag', function() { describe('useragent attribute', function() { it('sets the user agent', function(done) { - var listener, referrer; - referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; - listener = function(e) { + var referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; + var listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); done(); @@ -172,10 +168,9 @@ describe(' tag', function() { describe('disablewebsecurity attribute', function() { it('does not disable web security when not set', function(done) { - var encoded, listener, src; - src = " "; - encoded = btoa(unescape(encodeURIComponent(src))); - listener = function(e) { + var src = " "; + var encoded = btoa(unescape(encodeURIComponent(src))); + var listener = function(e) { assert(/Not allowed to load local resource/.test(e.message)); webview.removeEventListener('console-message', listener); done(); @@ -186,10 +181,9 @@ describe(' tag', function() { }); it('disables web security when set', function(done) { - var encoded, listener, src; - src = " "; - encoded = btoa(unescape(encodeURIComponent(src))); - listener = function(e) { + var src = " "; + var encoded = btoa(unescape(encodeURIComponent(src))); + var listener = function(e) { assert.equal(e.message, 'ok'); webview.removeEventListener('console-message', listener); done(); @@ -223,8 +217,7 @@ describe(' tag', function() { }); it('isolates storage for different id', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, " 0"); webview.removeEventListener('console-message', listener); done(); @@ -237,8 +230,7 @@ describe(' tag', function() { }); it('uses current session storage when no id is provided', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, "one 1"); webview.removeEventListener('console-message', listener); done(); @@ -252,8 +244,7 @@ describe(' tag', function() { describe('allowpopups attribute', function() { it('can not open new window when not set', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'null'); webview.removeEventListener('console-message', listener); done(); @@ -264,8 +255,7 @@ describe(' tag', function() { }); it('can open new window when set', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'window'); webview.removeEventListener('console-message', listener); done(); @@ -327,9 +317,8 @@ describe(' tag', function() { describe('page-favicon-updated event', function() { it('emits when favicon urls are received', function(done) { webview.addEventListener('page-favicon-updated', function(e) { - var pageUrl; assert.equal(e.favicons.length, 2); - pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; + var pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; assert.equal(e.favicons[0], pageUrl); done(); }); @@ -350,10 +339,9 @@ describe(' tag', function() { }); describe('did-navigate event', function() { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); + var p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -370,10 +358,9 @@ describe(' tag', function() { }); describe('did-navigate-in-page event', function() { it('emits when an anchor link is clicked', function(done) { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -396,10 +383,9 @@ describe(' tag', function() { }); it('emits when window.location.hash is changed', function(done) { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -425,8 +411,7 @@ describe(' tag', function() { describe('devtools-opened event', function() { it('should fire when webview.openDevTools() is called', function(done) { - var listener; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-opened', listener); webview.closeDevTools(); done(); @@ -442,12 +427,11 @@ describe(' tag', function() { describe('devtools-closed event', function() { it('should fire when webview.closeDevTools() is called', function(done) { - var listener, listener2; - listener2 = function() { + var listener2 = function() { webview.removeEventListener('devtools-closed', listener2); done(); }; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-opened', listener); webview.closeDevTools(); }; @@ -463,8 +447,7 @@ describe(' tag', function() { describe('devtools-focused event', function() { it('should fire when webview.openDevTools() is called', function(done) { - var listener; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-focused', listener); webview.closeDevTools(); done(); @@ -480,13 +463,12 @@ describe(' tag', function() { describe('.reload()', function() { it('should emit beforeunload handler', function(done) { - var listener, listener2; - listener = function(e) { + var listener = function(e) { assert.equal(e.channel, 'onbeforeunload'); webview.removeEventListener('ipc-message', listener); done(); }; - listener2 = function() { + var listener2 = function() { webview.reload(); webview.removeEventListener('did-finish-load', listener2); }; @@ -500,8 +482,7 @@ describe(' tag', function() { describe('.clearHistory()', function() { it('should clear the navigation history', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.channel, 'history'); assert.equal(e.args[0], 2); assert(webview.canGoBack()); @@ -518,14 +499,12 @@ describe(' tag', function() { }); describe('basic auth', function() { - var auth; - auth = require('basic-auth'); + var auth = require('basic-auth'); + it('should authenticate with correct credentials', function(done) { - var message, server; - message = 'Authenticated'; - server = http.createServer(function(req, res) { - var credentials; - credentials = auth(req); + var message = 'Authenticated'; + var server = http.createServer(function(req, res) { + var credentials = auth(req); if (credentials.name === 'test' && credentials.pass === 'test') { res.end(message); } else { @@ -534,8 +513,7 @@ describe(' tag', function() { server.close(); }); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, message); done(); @@ -549,11 +527,9 @@ describe(' tag', function() { describe('dom-ready event', function() { it('emits when document is loaded', function(done) { - var server; - server = http.createServer(function() {}); + var server = http.createServer(function() {}); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; webview.addEventListener('dom-ready', function() { done(); }); @@ -575,14 +551,12 @@ describe(' tag', function() { } it('should support user gesture', function(done) { - var listener, listener2; - listener = function() { + var listener = function() { webview.removeEventListener('enter-html-full-screen', listener); done(); }; - listener2 = function() { - var jsScript; - jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; + var listener2 = function() { + var jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; webview.executeJavaScript(jsScript, true); webview.removeEventListener('did-finish-load', listener2); }; @@ -634,8 +608,7 @@ describe(' tag', function() { describe('media-started-playing media-paused events', function() { it('emits when audio starts and stops playing', function(done) { - var audioPlayed; - audioPlayed = false; + var audioPlayed = false; webview.addEventListener('media-started-playing', function() { audioPlayed = true; }); @@ -650,9 +623,8 @@ describe(' tag', function() { describe('found-in-page event', function() { it('emits when a request is made', function(done) { - var listener, listener2, requestId; - requestId = null; - listener = function(e) { + var requestId = null; + var listener = function(e) { assert.equal(e.result.requestId, requestId); if (e.result.finalUpdate) { assert.equal(e.result.matches, 3); @@ -660,7 +632,7 @@ describe(' tag', function() { done(); } }; - listener2 = function() { + var listener2 = function() { requestId = webview.findInPage("virtual"); }; webview.addEventListener('found-in-page', listener); From a252b9b5702ae171af8a56d9ca73d3c20814d8c2 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 16:31:26 -0500 Subject: [PATCH 077/132] Initial ISSUE_TEMPLATE draft --- ISSUE_TEMPLATE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000000..b19649cad845 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ +### Flow + +* [ ] Bug + * [ ] Did you create a code snippet that reliably reproduces the issue in an isolated environment? + * [ ] Did you include what operating system you were on? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? + * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/electron/blob/master/CONTRIBUTING.md#submitting-issues). +* [ ] Enhancement + * [ ] Are you running the [latest version of Electron](https://github.com/atom/electron/releases)? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already requested? + +### Description + +[Description of the bug or feature] + +### Repro Steps + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected:** [What you expected to happen] + +**Actual:** [What actually happened] From f81f4479b62b02a2dab8804ba8968c76b29dfa4f Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 21:29:36 -0500 Subject: [PATCH 078/132] Drastically simplify the template [ci skip] --- ISSUE_TEMPLATE.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index b19649cad845..4b32023e9252 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,24 +1,11 @@ -### Flow +### Prerequisites -* [ ] Bug - * [ ] Did you create a code snippet that reliably reproduces the issue in an isolated environment? - * [ ] Did you include what operating system you were on? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? - * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/electron/blob/master/CONTRIBUTING.md#submitting-issues). -* [ ] Enhancement - * [ ] Are you running the [latest version of Electron](https://github.com/atom/electron/releases)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already requested? +* [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? ### Description -[Description of the bug or feature] +[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] -### Repro Steps +Electron version: -1. [First Step] -2. [Second Step] -3. [and so on...] - -**Expected:** [What you expected to happen] - -**Actual:** [What actually happened] +Operating system: From 1f248e6ea6e966c3023c5520aa3d91c07b393564 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 21:41:14 -0500 Subject: [PATCH 079/132] :memo: Move Electron and OS versions above the description [ci skip] --- ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 4b32023e9252..d2d66066f401 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -4,8 +4,8 @@ ### Description -[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] - Electron version: Operating system: + +[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] From 651264d098f05735473fde1dae2636fb0af35268 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 11:39:35 +0800 Subject: [PATCH 080/132] spec: Fix failing tests on Windows --- spec/api-debugger-spec.js | 4 +++- vendor/node | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 714d5fda48c5..56b642e76e43 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -95,7 +95,9 @@ describe('debugger module', function() { }); it('fires message event', function(done) { - var url = 'file://' + path.join(fixtures, 'pages', 'a.html'); + var url = process.platform != 'win32' ? + 'file://' + path.join(fixtures, 'pages', 'a.html') : + 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/'); w.webContents.loadURL(url); try { w.webContents.debugger.attach(); diff --git a/vendor/node b/vendor/node index a130651f868f..a507a3c3816d 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a130651f868f5ad23cb366abacea02f9ed50b769 +Subproject commit a507a3c3816d6ac085ed46250c489a3d76ab8b3c From 1e894df102f685f0959f8137d83176c93d457930 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 12:14:25 +0800 Subject: [PATCH 081/132] Update libchromiumcontent, fix #3666 --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 004e87dd0700..02e06948866f 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '1be1a55abba527d6fb0fc2a589cbaef2f5a6a79e' +LIBCHROMIUMCONTENT_COMMIT = 'fc5174471ccccce7030d0960f5228e73ca7c2ac6' PLATFORM = { 'cygwin': 'win32', From 9c9759a683436a8d35ec593ecc18512d47512fb9 Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Wed, 17 Feb 2016 21:30:01 -0800 Subject: [PATCH 082/132] Link to Menu documentation Added link to documentation about `Menu` objects --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index f88d02979941..b5f8e919b82e 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -515,7 +515,7 @@ Shows the dock icon. ### `app.dock.setMenu(menu)` _OS X_ -* `menu` Menu +* `menu` [Menu](menu.md) Sets the application's [dock menu][dock-menu]. From 12569f2c9d7a21eda65fd0656f92d2aedea35f68 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 18:32:13 +0800 Subject: [PATCH 083/132] mac: Simulate the behavior of cmd+~ when OS X didn't handle it --- atom/browser/native_window_mac.mm | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 7967a1771735..9d9f2a2392d1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -892,12 +892,25 @@ void NativeWindowMac::HandleKeyboardEvent( return; BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event]; - if (!handled && event.os_event.window != window_.get()) { - // The event comes from detached devtools view, and it has already been - if (!handled && (event.os_event.modifierFlags & NSCommandKeyMask) && - (event.os_event.keyCode == 50 /* ~ key */)) { - // Handle the cmd+~ shortcut. - Focus(true); + if (!handled && event.os_event.window) { + // Handle the cmd+~ shortcut. + if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ && + (event.os_event.keyCode == 50 /* ~ */)) { + // Switch to next visible window. + NSArray* windows = [NSApp windows]; + NSIndexSet* indexes = [windows indexesOfObjectsPassingTest: + ^BOOL(id window, NSUInteger idx, BOOL* stop) { + return [window isVisible]; + }]; + if ([indexes count] == 0) + return; + NSUInteger current = [windows indexOfObject:event.os_event.window]; + if (current == NSNotFound) // Some faked event. + return; + NSUInteger next = [indexes indexGreaterThanIndex:current]; + if (next == NSNotFound) + next = [indexes firstIndex]; + [[windows objectAtIndex:next] makeKeyAndOrderFront:nil]; } } } From 35815387abd1bbbc147a73a8161a99f7111e8691 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 18:57:31 +0800 Subject: [PATCH 084/132] Ship ffmpeg in dist, close #4536 --- script/create-dist.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/create-dist.py b/script/create-dist.py index a619e04d3ea0..2ec67d4f6c52 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -38,6 +38,7 @@ TARGET_BINARIES = { 'libGLESv2.dll', 'msvcp120.dll', 'msvcr120.dll', + 'ffmpeg.dll', 'node.dll', 'pdf.dll', 'content_resources_200_percent.pak', @@ -51,6 +52,7 @@ TARGET_BINARIES = { PROJECT_NAME, # 'electron' 'content_shell.pak', 'icudtl.dat', + 'libffmpeg.so', 'libnode.so', 'natives_blob.bin', 'snapshot_blob.bin', From 0d77fd4a2c7af3ac05d7c4a023e28c8420e6c20c Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 13:27:46 +0530 Subject: [PATCH 085/132] remote: return webcontents instance from cache --- atom/renderer/api/lib/remote.js | 7 +++++++ spec/api-ipc-spec.js | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index ad01e77ac51b..d8a5508621e0 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -1,11 +1,14 @@ const ipcRenderer = require('electron').ipcRenderer; const CallbacksRegistry = require('electron').CallbacksRegistry; const v8Util = process.atomBinding('v8_util'); +const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap; const callbacksRegistry = new CallbacksRegistry; var includes = [].includes; +var remoteObjectCache = new IDWeakMap; + // Check for circular reference. var isCircular = function(field, visited) { if (typeof field === 'object') { @@ -154,6 +157,9 @@ var metaToValue = function(meta) { } } + if (remoteObjectCache.has(meta.id)) + return remoteObjectCache.get(meta.id); + // Track delegate object's life time, and tell the browser to clean up // when the object is GCed. v8Util.setDestructor(ret, function() { @@ -162,6 +168,7 @@ var metaToValue = function(meta) { // Remember object's id. v8Util.setHiddenValue(ret, 'atomId', meta.id); + remoteObjectCache.set(meta.id, ret); return ret; } }; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 2c8bc28f1560..9cf741412b08 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -90,6 +90,14 @@ describe('ipc module', function() { }); }); + describe('remote webContents', function() { + it('can return same object with different getters', function() { + var contents1 = remote.getCurrentWindow().webContents; + var contents2 = remote.getCurrentWebContents(); + assert(contents1 == contents2); + }); + }); + describe('ipc.sender.send', function() { it('should work when sending an object containing id property', function(done) { var obj = { From 68f48c9456dbca1d5e84b92f3d93ffa8e0808c7a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 23:28:19 +0800 Subject: [PATCH 086/132] docs: Add note on Chrome version when using widevine Refs #4519. --- docs/tutorial/using-widevine-cdm-plugin.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tutorial/using-widevine-cdm-plugin.md b/docs/tutorial/using-widevine-cdm-plugin.md index 340dad343c8a..630c18ab8e5f 100644 --- a/docs/tutorial/using-widevine-cdm-plugin.md +++ b/docs/tutorial/using-widevine-cdm-plugin.md @@ -8,6 +8,10 @@ Electron doesn't ship with the Widevine CDM plugin for license reasons, to get it, you need to install the official Chrome browser first, which should match the architecture and Chrome version of the Electron build you use. +__Note:__ The major version of Chrome browser has to be the same with the Chrome +version used by Electron, otherwise the plugin will not work even though +`navigator.plugins` would show it has been loaded. + ### Windows & OS X Open `chrome://components/` in Chrome browser, find `WidevineCdm` and make From 8ce3ab1e262ef4ab641d3083ce5be711ea8afd0d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 17 Feb 2016 22:46:36 +0900 Subject: [PATCH 087/132] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/api/session.md | 9 ++++++++- docs-translations/ko-KR/api/shell.md | 8 ++++++-- docs-translations/ko-KR/api/tray.md | 7 +++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 32412d13180b..89cc17322637 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -523,7 +523,7 @@ dock 아이콘을 표시합니다. ### `app.dock.setMenu(menu)` _OS X_ -* `menu` Menu +* `menu` [Menu](menu.md) 어플리케이션의 [dock menu][dock-menu]를 설정합니다. diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 5598fb6eb260..5bb4867eda0e 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -59,7 +59,8 @@ var ses = session.fromPartition('persist:name'); Electron의 `webContents`에서 `item`을 다운로드할 때 발생하는 이벤트입니다. -`event.preventDefault()` 메서드를 호출하면 다운로드를 취소합니다. +`event.preventDefault()` 메서드를 호출하면 다운로드를 취소하고, 프로세스의 다음 +틱부터 `item`을 사용할 수 없게 됩니다. ```javascript session.defaultSession.on('will-download', function(event, item, webContents) { @@ -313,6 +314,12 @@ session.fromPartition(partition).setPermissionRequestHandler(function(webContent }); ``` +#### `ses.clearHostResolverCache([callback])` + +* `callback` Function (optional) - 작업이 완료되면 호출됩니다. + +호스트 리소버(resolver) 캐시를 지웁니다. + #### `ses.webRequest` `webRequest` API는 생명주기의 다양한 단계에 맞춰 요청 컨텐츠를 가로채거나 변경할 수 diff --git a/docs-translations/ko-KR/api/shell.md b/docs-translations/ko-KR/api/shell.md index 4183d3b2502d..c4831092f3cf 100644 --- a/docs-translations/ko-KR/api/shell.md +++ b/docs-translations/ko-KR/api/shell.md @@ -25,12 +25,16 @@ shell.openExternal('https://github.com'); 지정한 파일을 데스크톱 기본 프로그램으로 엽니다. -### `shell.openExternal(url)` +### `shell.openExternal(url[, options])` * `url` String +* `options` Object (optional) _OS X_ + * `activate` Boolean - `true`로 설정하면 어플리케이션을 바로 활성화 상태로 + 실행합니다. 기본값은 `true`입니다. 제공된 외부 프로토콜 URL을 기반으로 데스크톱의 기본 프로그램으로 엽니다. (예를 들어 -mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) +mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) 어플리케이션이 해당 URL을 +열 수 있을 때 `true`를 반환합니다. 아니라면 `false`를 반환합니다. 역주: 폴더는 'file:\\\\C:\\'와 같이 지정하여 열 수 있습니다. (Windows의 경우) diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index e182f6471e7a..d82b0a9d7e40 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -32,6 +32,13 @@ __플랫폼별 한계:__ 트레이 아이콘이 작동하도록 만들 수 있습니다. * 앱 알림 표시기는 컨텍스트 메뉴를 가지고 있을 때만 보입니다. * Linux에서 앱 표시기가 사용될 경우, `click` 이벤트는 무시됩니다. +* Linux에서 각각 개별 `MenuItem`의 변경을 적용하려면 `setContextMenu`를 다시 + 호출해야 합니다. 예를 들면: + +```javascript +contextMenu.items[2].checked = false; +appIcon.setContextMenu(contextMenu); +``` 이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 의존해선 안되며 언제나 컨텍스트 메뉴를 포함해야 합니다. From cc6ba0fd10e852d17fb46fbf37ad2f62c1238935 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 18 Feb 2016 08:57:31 -0800 Subject: [PATCH 088/132] Remove all but prompts for version numbers --- ISSUE_TEMPLATE.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index d2d66066f401..a78e30d8620b 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,11 +1,2 @@ -### Prerequisites - -* [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? - -### Description - -Electron version: - -Operating system: - -[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] +* Electron version: +* Operating system: From c4859c3dc6a7167936db275a1e58398d46757807 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:51:24 -0800 Subject: [PATCH 089/132] Use colors from Electron site --- atom/browser/default_app/index.html | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index ec16a38bc423..95080867bcd3 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -3,23 +3,23 @@ Electron From 9b373f2e152d3642af0fe613185edde9735237fa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:10:36 -0800 Subject: [PATCH 096/132] on -> to learn --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 915a38fe792d..3abcefd914b9 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -121,7 +121,7 @@ `docs` ); - on how to write one. + to learn how to write one.

From 1c377310651144de398cb93c477b0d755bfdcc7a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:11:35 -0800 Subject: [PATCH 097/132] under -> in --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 3abcefd914b9..c5672466bcce 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -98,7 +98,7 @@

- To run your app with Electron, execute the following command under your + To run your app with Electron, execute the following command in your Console (or Terminal):

From d3c6075841ec280cd14e9c4fa73a8ad1cff4e1f3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:21:05 -0800 Subject: [PATCH 098/132] Use background color as border color --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index c5672466bcce..80c347eff6dd 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -33,7 +33,7 @@ pre, code { font-family: "Menlo","Lucida Console",monospace; - border: 1px solid #ddd; + border: 1px solid #076274; background-color: #076274; color: #C5F3FC; border-radius: 3px; From 2a6fcf48e51b1d9125a8cf42c3a348028d73237f Mon Sep 17 00:00:00 2001 From: Brad Metcalf Date: Thu, 18 Feb 2016 13:41:22 -0600 Subject: [PATCH 099/132] Changed session to app to reflect rest of document --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index b5f8e919b82e..bdf0a8a55870 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -156,7 +156,7 @@ certificate you should prevent the default behavior with `event.preventDefault()` and call `callback(true)`. ```javascript -session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { +app.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { // Verification logic. event.preventDefault(); From 632c18ab370b7fab418a8cdfc301b8f1beb7f855 Mon Sep 17 00:00:00 2001 From: Rafael G Firmino Date: Thu, 18 Feb 2016 22:51:23 -0200 Subject: [PATCH 100/132] Translated --- docs-translations/pt-BR/api/window-open.md | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 docs-translations/pt-BR/api/window-open.md diff --git a/docs-translations/pt-BR/api/window-open.md b/docs-translations/pt-BR/api/window-open.md new file mode 100644 index 000000000000..eb2b31cd0e4e --- /dev/null +++ b/docs-translations/pt-BR/api/window-open.md @@ -0,0 +1,67 @@ +# The `window.open` function + +Qunado `window.open` é chamado para criar uma nova janela de uma pagina web uma nova instância de `BrowserWindow` será criado para a `url` e um proxy será devolvido para o `windows.open`, para permitir que a página tenha limitado controle sobre ele. + +O proxy tem funcionalidade limitada padrão implementada para ser compatível com as páginas web tradicionais. +Para controle total da nova janela você deveria criar um `BrowserWindow` diretamente + + +The newly created `BrowserWindow` will inherit parent window's options by +default, to override inherited options you can set them in the `features` +string. + +O recém-criado `BrowserWindow` herdará as opções da janela pai por padrão, para substituir as opções herdadas você pode definilos no `features`(string). +### `window.open(url[, frameName][, features])` + +* `url` String +* `frameName` String (opcional) +* `features` String (opcional) + +Cria uma nova janela e retorna uma instância da classe `BrowserWindowProxy'. + +A string `features` segue o formato padrão do browser, mas cada recurso (feature) tem que ser um campo de opções do `BrowserWindow`. + +### `window.opener.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + +Envia uma mensagem para a janela pai com a origem especificada ou `*` preferência de origem não especificada. +Sends a message to the parent window with the specified origin or `*` +origin preference. + +## Class: BrowserWindowProxy + +O objeto `BrowserWindowProxy` é retornado de `window.open` e fornece uma funcionalidade limitada para a janela filha. + +### `BrowserWindowProxy.blur()` + +Remove o foco da janela filha. + +### `BrowserWindowProxy.close()` + +Forçadamente fecha a janela filha sem chamar o evento de descarregamento. + +### `BrowserWindowProxy.closed` + +Define como true após a janela filha ficar fechada. + +### `BrowserWindowProxy.eval(code)` + +* `code` String + +Avalia o código na jánela filha. + +### `BrowserWindowProxy.focus()` + +Concentra-se a janela filha (traz a janela para frente) +### `BrowserWindowProxy.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + +Sends a message to the child window with the specified origin or `*` for no +origin preference. + +In addition to these methods, the child window implements `window.opener` object +with no properties and a single method. From cd303087110f76d3232498456b02958ea03fea17 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:01:39 +0800 Subject: [PATCH 101/132] Update libchromiumcontent with free version of ffmpeg --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 02e06948866f..e3404918ce4e 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'fc5174471ccccce7030d0960f5228e73ca7c2ac6' +LIBCHROMIUMCONTENT_COMMIT = '599c8941e1884e155218ec1013cba9fc5c7c7072' PLATFORM = { 'cygwin': 'win32', From daffb4881ee72c2299a407d78a6d9296e5050bec Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:26:18 +0800 Subject: [PATCH 102/132] Create and upload free version of ffmpeg --- script/create-dist.py | 19 +++++++++++++++++++ script/upload.py | 12 ++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/script/create-dist.py b/script/create-dist.py index 2ec67d4f6c52..32d8f52aff37 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -99,6 +99,7 @@ def main(): create_dist_zip() create_chrome_binary_zip('chromedriver', get_chromedriver_version()) create_chrome_binary_zip('mksnapshot', ATOM_SHELL_VERSION) + create_ffmpeg_zip() create_symbols_zip() @@ -205,6 +206,24 @@ def create_chrome_binary_zip(binary, version): make_zip(zip_file, files, []) +def create_ffmpeg_zip(): + dist_name = 'ffmpeg-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) + + if PLATFORM == 'darwin': + ffmpeg_name = 'libffmpeg.dylib' + elif PLATFORM == 'linux': + ffmpeg_name = 'libffmpeg.so' + elif PLATFORM == 'win32': + ffmpeg_name = 'ffmpeg.dll' + + shutil.copy2(os.path.join(CHROMIUM_DIR, '..', 'ffmpeg', ffmpeg_name), + DIST_DIR) + with scoped_cwd(DIST_DIR): + make_zip(zip_file, [ffmpeg_name, 'LICENSE', 'LICENSES.chromium.html'], []) + + def create_symbols_zip(): dist_name = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, diff --git a/script/upload.py b/script/upload.py index 3245d9caaa76..d23bc554c3cc 100755 --- a/script/upload.py +++ b/script/upload.py @@ -35,9 +35,6 @@ DSYM_NAME = '{0}-{1}-{2}-{3}-dsym.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) -MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION, - get_platform_key(), - get_target_arch()) def main(): @@ -89,12 +86,19 @@ def main(): if PLATFORM == 'darwin': upload_atom_shell(github, release, os.path.join(DIST_DIR, DSYM_NAME)) + # Upload free version of ffmpeg. + ffmpeg = 'ffmpeg-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + upload_atom_shell(github, release, os.path.join(DIST_DIR, ffmpeg)) + # Upload chromedriver and mksnapshot for minor version update. if parse_version(args.version)[2] == '0': chromedriver = 'chromedriver-{0}-{1}-{2}.zip'.format( get_chromedriver_version(), get_platform_key(), get_target_arch()) upload_atom_shell(github, release, os.path.join(DIST_DIR, chromedriver)) - upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) + mksnapshot = 'mksnapshot-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + upload_atom_shell(github, release, os.path.join(DIST_DIR, mksnapshot)) if PLATFORM == 'win32' and not tag_exists: # Upload node headers. From 4b18317e7c2a05e440e8a04c3ab4a12f4b573dcd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:27:04 +0800 Subject: [PATCH 103/132] Bump v0.36.8 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index c8c714858b43..68a30cc637f3 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.7', + 'version%': '0.36.8', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 74725c94dc5f..e1a5694d27ad 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.7 + 0.36.8 CFBundleShortVersionString - 0.36.7 + 0.36.8 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 298d0bce73cf..ff125b3edf72 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,7,0 - PRODUCTVERSION 0,36,7,0 + FILEVERSION 0,36,8,0 + PRODUCTVERSION 0,36,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.7" + VALUE "FileVersion", "0.36.8" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.7" + VALUE "ProductVersion", "0.36.8" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index a4f886c7e7d5..b464ebdae4fd 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 7 +#define ATOM_PATCH_VERSION 8 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index f684386269e2..a7eaa1a94204 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.7", + "version": "0.36.8", "devDependencies": { "asar": "^0.9.0", "eslint": "^2.1.0", From 85800256deb7c2eb543bba8d28eb369e3521eb54 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 19 Feb 2016 19:39:01 +0530 Subject: [PATCH 104/132] protocol: respect requests from partition --- atom/browser/api/atom_api_protocol.cc | 70 +++++++++++---------------- atom/browser/api/atom_api_protocol.h | 11 +++-- atom/browser/api/atom_api_session.cc | 10 ++++ atom/browser/api/atom_api_session.h | 2 + atom/browser/api/lib/protocol.js | 9 +++- atom/common/node_bindings.cc | 1 - spec/api-protocol-spec.js | 51 +++++++++++++++++++ 7 files changed, 105 insertions(+), 49 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 09da9c71cadb..335c20e11e3b 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -28,33 +28,6 @@ Protocol::Protocol(AtomBrowserContext* browser_context) CHECK(job_factory_); } -mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) - .SetMethod("registerServiceWorkerSchemes", - &Protocol::RegisterServiceWorkerSchemes) - .SetMethod("registerStringProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerBufferProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerHttpProtocol", - &Protocol::RegisterProtocol) - .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) - .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) - .SetMethod("interceptStringProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptBufferProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptHttpProtocol", - &Protocol::InterceptProtocol) - .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); -} - void Protocol::RegisterStandardSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomSchemes(schemes); @@ -153,21 +126,34 @@ mate::Handle Protocol::Create( return mate::CreateHandle(isolate, new Protocol(browser_context)); } +// static +void Protocol::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) + .SetMethod("registerServiceWorkerSchemes", + &Protocol::RegisterServiceWorkerSchemes) + .SetMethod("registerStringProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerBufferProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerFileProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerHttpProtocol", + &Protocol::RegisterProtocol) + .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) + .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) + .SetMethod("interceptStringProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptBufferProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptFileProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptHttpProtocol", + &Protocol::InterceptProtocol) + .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); +} + } // namespace api } // namespace atom - -namespace { - -void Initialize(v8::Local exports, v8::Local unused, - v8::Local context, void* priv) { - v8::Isolate* isolate = context->GetIsolate(); - mate::Dictionary dict(isolate, exports); - auto browser_context = static_cast( - atom::AtomBrowserMainParts::Get()->browser_context()); - dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context)); -} - -} // namespace - -NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize) diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 8aef406fbc38..36ab46ba8231 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -9,6 +9,7 @@ #include #include +#include "atom/browser/api/trackable_object.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "base/callback.h" #include "base/containers/scoped_ptr_hash_map.h" @@ -30,7 +31,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::Wrappable { +class Protocol : public mate::TrackableObject { public: using Handler = base::Callback)>; @@ -40,13 +41,13 @@ class Protocol : public mate::Wrappable { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); + // mate::TrackableObject: + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: explicit Protocol(AtomBrowserContext* browser_context); - // mate::Wrappable implementations: - virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate); - private: // Possible errors. enum ProtocolError { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index e5c5198f0341..51f7c1bb811c 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" +#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/save_page_handler.h" @@ -443,6 +444,14 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { return v8::Local::New(isolate, cookies_); } +v8::Local Session::Protocol(v8::Isolate* isolate) { + if (protocol_.IsEmpty()) { + auto handle = atom::api::Protocol::Create(isolate, browser_context()); + protocol_.Reset(isolate, handle.ToV8()); + } + return v8::Local::New(isolate, protocol_); +} + v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { auto handle = atom::api::WebRequest::Create(isolate, browser_context()); @@ -490,6 +499,7 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::SetPermissionRequestHandler) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) + .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 02d8ba5cdec0..63c4cfc612bd 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -80,10 +80,12 @@ class Session: public mate::TrackableObject, mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); + v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); // Cached object. v8::Global cookies_; + v8::Global protocol_; v8::Global web_request_; scoped_refptr browser_context_; diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index 41cb48db09b9..caef0ad646b4 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -4,7 +4,10 @@ if (!app.isReady()) { throw new Error('Can not initialize protocol module before app is ready'); } -const protocol = process.atomBinding('protocol').protocol; +const session = require('electron').session; + +// Returns the protocol property for default session. +const protocol = session.defaultSession.protocol; // Warn about removed APIs. var logAndThrow = function(callback, message) { @@ -16,6 +19,10 @@ var logAndThrow = function(callback, message) { } }; +protocol.fromPartition = function(partition) { + return session.fromPartition(partition).protocol; +}; + protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 69e7906ffbbb..4af3ba5b64be 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -41,7 +41,6 @@ REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_power_monitor); REFERENCE_MODULE(atom_browser_power_save_blocker); -REFERENCE_MODULE(atom_browser_protocol); REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_tray); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 215868bfdc8a..483155b70652 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -3,6 +3,7 @@ const http = require('http'); const path = require('path'); const qs = require('querystring'); const remote = require('electron').remote; +const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; describe('protocol module', function() { @@ -814,4 +815,54 @@ describe('protocol module', function() { }); }); }); + + describe('protocol.fromPartition', function() { + var partitionName = 'temp'; + var tempProtocol = protocol.fromPartition(partitionName); + var w = null; + + beforeEach(function() { + if (w != null) { + w.destroy(); + } + w = new BrowserWindow({ + show: false, + width: 400, + height: 400, + webPreferences: { + partition: partitionName + } + }); + }); + + afterEach(function() { + if (w != null) { + w.destroy(); + } + w = null; + }); + + it('handles requests from a partition', function(done) { + var handler = function(error, callback) { + callback({ + data: text + }); + }; + tempProtocol.registerStringProtocol(protocolName, handler, function(error) { + if (error) { + return done(error); + } + protocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, false); + }); + tempProtocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, true); + }); + }); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); + }); + }); }); From e45e2460275fafd965aab20354d17c86d01f5b35 Mon Sep 17 00:00:00 2001 From: cesine Date: Fri, 19 Feb 2016 23:24:56 -0500 Subject: [PATCH 105/132] a new version of asar is out 0.10.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f684386269e2..78618c06bd95 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "electron", "version": "0.36.7", "devDependencies": { - "asar": "^0.9.0", + "asar": "^0.10.0", "eslint": "^2.1.0", "request": "*" }, From a737e15ddba97227a83a6cd3bf3cacafb0935ee2 Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 16:09:56 +0800 Subject: [PATCH 106/132] Update README.md to 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/README.md | 76 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/docs-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index 5c4303a0a6f8..d7a8442ad4a3 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -1,13 +1,19 @@ +## 常见问题 + ++ [Electron 常见问题](faq/electron-faq.md) + ## 向导 * [支持平台](tutorial/supported-platforms.md) -* [应用部署](tutorial/application-distribution.md) -* [应用打包](tutorial/application-packaging.md) -* [使用原生模块](tutorial/using-native-node-modules.md) +* [分发应用](tutorial/application-distribution.md) +* [提交应用到 Mac App Store](tutorial/mac-app-store-submission-guide.md) +* [打包应用](tutorial/application-packaging.md) +* [使用 Node 原生模块](tutorial/using-native-node-modules.md) * [主进程调试](tutorial/debugging-main-process.md) * [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md) -* [调试工具扩展](tutorial/devtools-extension.md) -* [使用 PepperFlash 插件](tutorial/using-pepper-flash-plugin.md) +* [使用开发人员工具扩展](tutorial/devtools-extension.md) +* [使用 Pepper Flash 插件](tutorial/using-pepper-flash-plugin.md) +* [使用 Widevine CDM 插件](tutorial/using-widevine-cdm-plugin.md) ## 教程 @@ -19,53 +25,55 @@ * [简介](api/synopsis.md) * [进程对象](api/process.md) -* [支持的Chrome命令行开关](api/chrome-command-line-switches.md) +* [支持的 Chrome 命令行开关](api/chrome-command-line-switches.md) +* [环境变量](api/environment-variables.md) -定制的DOM元素: +自定义的 DOM 元素: -* [`File`对象](api/file-object.md) -* [``标签](api/web-view-tag.md) -* [`window.open`函数](api/window-open.md) +* [`File` 对象](api/file-object.md) +* [`` 标签](api/web-view-tag.md) +* [`window.open` 函数](api/window-open.md) -主进程可用的模块: +在主进程内可用的模块: * [app](api/app.md) -* [auto-updater](api/auto-updater.md) -* [browser-window](api/browser-window.md) -* [content-tracing](api/content-tracing.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow](api/browser-window.md) +* [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) -* [global-shortcut](api/global-shortcut.md) -* [ipc (main process)](api/ipc-main-process.md) -* [menu](api/menu.md) -* [menu-item](api/menu-item.md) -* [power-monitor](api/power-monitor.md) -* [power-save-blocker](api/power-save-blocker.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) +* [Tray](api/tray.md) -渲染进程(网页)可用的模块: +在渲染进程(网页)内可用的模块: -* [ipc (renderer)](api/ipc-renderer.md) +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) * [remote](api/remote.md) -* [web-frame](api/web-frame.md) +* [webFrame](api/web-frame.md) -两种进程都可用的模块: +在两种进程中都可用的模块: * [clipboard](api/clipboard.md) -* [crash-reporter](api/crash-reporter.md) -* [native-image](api/native-image.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) * [screen](api/screen.md) * [shell](api/shell.md) ## 开发 -* [编码规范](development/coding-style.md) +* [代码规范](development/coding-style.md) * [源码目录结构](development/source-code-directory-structure.md) -* [与 NW.js (原名 node-webkit) 在技术上的差异](development/atom-shell-vs-node-webkit.md) -* [构建系统概况](development/build-system-overview.md) -* [构建步骤 (Mac)](development/build-instructions-mac.md) -* [构建步骤 (Windows)](development/build-instructions-windows.md) -* [构建步骤 (Linux)](development/build-instructions-linux.md) -* [在调试中使用 SymbolServer](development/setting-up-symbol-server.md) +* [与 NW.js(原 node-webkit)在技术上的差异](development/atom-shell-vs-node-webkit.md) +* [构建系统概览](development/build-system-overview.md) +* [构建步骤(Mac)](development/build-instructions-mac.md) +* [构建步骤(Windows)](development/build-instructions-windows.md) +* [构建步骤(Linux)](development/build-instructions-linux.md) +* [在调试中使用 Symbol Server](development/setting-up-symbol-server.md) From 060d06d39676049d66b6598b8773604864a87dca Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 17:00:58 +0800 Subject: [PATCH 107/132] Translate electron-faq.md#45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/faq/electron-faq.md | 139 ++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs-translations/zh-CN/faq/electron-faq.md diff --git a/docs-translations/zh-CN/faq/electron-faq.md b/docs-translations/zh-CN/faq/electron-faq.md new file mode 100644 index 000000000000..3431c6018ab2 --- /dev/null +++ b/docs-translations/zh-CN/faq/electron-faq.md @@ -0,0 +1,139 @@ +# Electron 常见问题 + +## Electron 会在什么时候升级到最新版本的 Chrome? + +通常来说,在稳定版的 Chrome 发布后两周内,我们会更新 Electron 内的 Chrome 版本。 + +我们只会使用 stable 版本的 Chrome。但如果在 beta 或 dev 版本中有一个重要的更新,我们会把补丁应用到现版本的 Chrome 上。 + +## Electron 会在什么时候升级到最新版本的 Node.js? + +我们通常会在最新版的 Node.js 发布后一个月左右将 Electron 更新到这个版本的 Node.js。我们通过这种方式来避免新版本的 Node.js +带来的 bug(这种 bug 太常见了)。 + +Node.js 的新特性通常是由新版本的 V8 带来的。由于 Electron 使用的是 Chrome 浏览器中附带的 V8 引擎,所以 Electron 内往往已经 +有了部分新版本 Node.js 才有的崭新特性。 + +## 如何在两个网页间共享数据? + +在两个网页(渲染进程)间共享数据最简单的方法是使用浏览器中已经实现的 HTML5 API,比较好的方案是用 [Storage API][storage], +[`localStorage`][local-storage],[`sessionStorage`][session-storage] 或者 [IndexedDB][indexed-db]。 + +你还可以用 Electron 内的 IPC 机制实现。将数据存在主进程的某个全局变量中,然后在多个渲染进程中使用 `remote` 模块来访问它。 + +```javascript +// 在主进程中 +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// 在第一个页面中 +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// 在第二个页面中 +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + +## 为什么应用的窗口、托盘在一段时间后不见了? + +这通常是因为用来存放窗口、托盘的变量被垃圾收集了。 + +你可以参考以下两篇文章来了解为什么会遇到这个问题。 + +* [内存管理][memory-management] +* [变量作用域][variable-scope] + +如果你只是要一个快速的修复方案,你可以用下面的方式改变变量的作用域,防止这个变量被垃圾收集。 + +从 + +```javascript +app.on('ready', function() { + var tray = new Tray('/path/to/icon.png'); +}) +``` + +改为 + +```javascript +var tray = null; +app.on('ready', function() { + tray = new Tray('/path/to/icon.png'); +}) +``` + +## 在 Electron 中,我为什么不能用 jQuery、RequireJS、Meteor、AngularJS? + +因为 Electron 在运行环境中引入了 Node.js,所以在 DOM 中有一些额外的变量,比如 `module`、`exports` 和 `require`。这导致 +了许多库不能正常运行,因为它们也需要将同名的变量加入运行环境中。 + +我们可以通过禁用 Node.js 来解决这个问题,用如下的方式: + +```javascript +// 在主进程中 +var mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: false + } +}); +``` + +假如你依然需要使用 Node.js 和 Electron 提供的 API,你需要在引入那些库之前将这些变量重命名,比如: + +```html + + + + +``` + +## 为什么 `require('electron').xxx` 的结果是 undefined? + +在使用 Electron 的提供的模块时,你可能会遇到和以下类似的错误: + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +这是因为你在项目中或者在全局中安装了[npm 上获取的 `electron` 模块][electron-module],它把 Electron 的内置模块覆写了。 + +你可以通过以下方式输出 `electron` 模块的路径来确认你是否使用了正确的模块。 + +```javascript +console.log(require.resolve('electron')); +``` + +确认以下它是不是像下面这样的: + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +假如输出的路径类似于 `node_modules/electron/index.js`,那么你需要移除或者重命名 npm 上的 `electron` 模块。 + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +如果你依然遇到了这个问题,你可能需要检查一下拼写或者是否在错误的进程中调用了这个模块。比如, +`require('electron').app` 只能在主进程中使用, 然而 `require('electron').webFrame` 只能在渲染进程中使用。 + +[memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management +[variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API From 1db72f8010e46567e16182e3f6cddf0155239c6c Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 18:51:04 +0800 Subject: [PATCH 108/132] Translate accelerator.md of 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/accelerator.md | 47 ++++++++++------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/docs-translations/zh-CN/api/accelerator.md b/docs-translations/zh-CN/api/accelerator.md index 8858d18e856e..06e7397c849a 100644 --- a/docs-translations/zh-CN/api/accelerator.md +++ b/docs-translations/zh-CN/api/accelerator.md @@ -1,46 +1,43 @@ # Accelerator -An accelerator is a string that represents a keyboard shortcut. It can contain -multiple modifiers and key codes, combined by the `+` character. +一个 `Accelerator` 是一个表示某个快捷键组合的字符串。它包含了用 `+` 连接的若干个按键。 -Examples: +例如: * `Command+A` * `Ctrl+Shift+Z` -## Platform notice +## 运行平台相关的提示 -On Linux and Windows, the `Command` key does not have any effect so -use `CommandOrControl` which represents `Command` on OS X and `Control` on -Linux and Windows to define some accelerators. +在 Linux 和 Windows 上,`Command` 键并不存在,因此我们通常用 `CommandOrControl` 来表示“在 OS X 下为 `Command` 键,但在 +Linux 和 Windows 下为 `Control` 键。 -The `Super` key is mapped to the `Windows` key on Windows and Linux and -`Cmd` on OS X. +`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 OS X 下为 `Command` 键。 -## Available modifiers +## 可用的功能按键 -* `Command` (or `Cmd` for short) -* `Control` (or `Ctrl` for short) -* `CommandOrControl` (or `CmdOrCtrl` for short) +* `Command`(缩写为 `Cmd`) +* `Control`(缩写为 `Ctrl`) +* `CommandOrControl`(缩写为 `CmdOrCtrl`) * `Alt` * `Shift` * `Super` -## Available key codes +## 可用的普通按键 -* `0` to `9` -* `A` to `Z` -* `F1` to `F24` -* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. +* `0` 到 `9` +* `A` 到 `Z` +* `F1` 到 `F24` +* 类似与 `~`、`!`、`@`、`#`、`$` 的标点符号。 * `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` +* `Return`(和 `Enter` 等同) +* `Up`、`Down`、`Left` 和 `Right` +* `Home` 和 `End` +* `PageUp` 和 `PageDown` +* `Escape`(缩写为 `Esc`) +* `VolumeUp`、`VolumeDown` 和 `VolumeMute` +* `MediaNextTrack`、`MediaPreviousTrack`、`MediaStop` 和 `MediaPlayPause` From f64dc5f57d1d11a5701b4391a9fbb5f679d28358 Mon Sep 17 00:00:00 2001 From: Magica Date: Sun, 21 Feb 2016 13:49:51 +0800 Subject: [PATCH 109/132] Translate app.md in commit 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/app.md | 301 ++++++++++++++--------------- 1 file changed, 146 insertions(+), 155 deletions(-) diff --git a/docs-translations/zh-CN/api/app.md b/docs-translations/zh-CN/api/app.md index 448a5a373e91..dd8d6bcfdf65 100644 --- a/docs-translations/zh-CN/api/app.md +++ b/docs-translations/zh-CN/api/app.md @@ -11,11 +11,11 @@ app.on('window-all-closed', function() { }); ``` -## 事件 +## 事件列表 `app` 对象会触发以下的事件: -### 事件: 'will-finish-launching' +### 事件:'will-finish-launching' 当应用程序完成基础的启动的时候被触发。在 Windows 和 Linux 中, `will-finish-launching` 事件与 `ready` 事件是相同的; 在 OS X 中, @@ -24,11 +24,11 @@ app.on('window-all-closed', function() { 在大多数的情况下,你应该只在 `ready` 事件处理器中完成所有的业务。 -### 事件: 'ready' +### 事件:'ready' 当 Electron 完成初始化时被触发。 -### 事件: 'window-all-closed' +### 事件:'window-all-closed' 当所有的窗口都被关闭时触发。 @@ -36,20 +36,20 @@ app.on('window-all-closed', function() { 或者开发者调用了 `app.quit()` ,Electron 将会先尝试关闭所有的窗口再触发 `will-quit` 事件, 在这种情况下 `window-all-closed` 不会被触发。 -### 事件: 'before-quit' +### 事件:'before-quit' 返回: -* `event` 事件 +* `event` Event 在应用程序开始关闭它的窗口的时候被触发。 调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 -### 事件: 'will-quit' +### 事件:'will-quit' 返回: -* `event` 事件 +* `event` Event 当所有的窗口已经被关闭,应用即将退出时被触发。 调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 @@ -57,20 +57,20 @@ app.on('window-all-closed', function() { 你可以在 `window-all-closed` 事件的描述中看到 `will-quit` 事件 和 `window-all-closed` 事件的区别。 -### 事件: 'quit' +### 事件:'quit' 返回: -* `event` 事件 -* `exitCode` 整数 +* `event` Event +* `exitCode` Integer 当应用程序正在退出时触发。 -### 事件: 'open-file' _OS X_ +### 事件:'open-file' _OS X_ 返回: -* `event` 事件 -* `path` 字符串 +* `event` Event +* `path` String 当用户想要在应用中打开一个文件时触发。`open-file` 事件常常在应用已经打开并且系统想要再次使用应用打开文件时被触发。 `open-file` 也会在一个文件被拖入 dock 且应用还没有运行的时候被触发。 @@ -78,73 +78,74 @@ app.on('window-all-closed', function() { 如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 在 Windows系统中, 你需要通过解析 process.argv 来获取文件路径。 -### 事件: 'open-url' _OS X_ + +### 事件:'open-url' _OS X_ 返回: -* `event` 事件 -* `url` 字符串 +* `event` Event +* `url` String 当用户想要在应用中打开一个url的时候被触发。URL格式必须要提前标识才能被你的应用打开。 如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 -### 事件: 'activate' _OS X_ +### 事件:'activate' _OS X_ 返回: -* `event` 事件 -* `hasVisibleWindows` 布尔值 +* `event` Event +* `hasVisibleWindows` Boolean 当应用被激活时触发,常用于点击应用的 dock 图标的时候。 -### 事件: 'browser-window-blur' +### 事件:'browser-window-blur' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 失去焦点的时候触发。 +当一个 [BrowserWindow](browser-window.md) 失去焦点的时候触发。 -### 事件: 'browser-window-focus' +### 事件:'browser-window-focus' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 获得焦点的时候触发。 +当一个 [BrowserWindow](browser-window.md) 获得焦点的时候触发。 -### 事件: 'browser-window-created' +### 事件:'browser-window-created' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 被创建的时候触发。 +当一个 [BrowserWindow](browser-window.md) 被创建的时候触发。 -### 事件: 'certificate-error' +### 事件:'certificate-error' 返回: -* `event` 事件 -* `webContents` [web组件](web-contents.md) -* `url` 字符串 -* `certificateList` 对象 - * `data` PEM 编码数据 - * `issuerName` 发行者的公有名称 -* `callback` 函数 +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `url` String - URL 地址 +* `error` String - 错误码 +* `certificate` Object + * `data` Buffer - PEM 编码数据 + * `issuerName` String - 发行者的公有名称 +* `callback` Function -Emitted when failed to verify the `certificate` for `url`, to trust the -certificate you should prevent the default behavior with -`event.preventDefault()` and call `callback(true)`. +当对 `url` 验证 `certificate` 证书失败的时候触发,如果需要信任这个证书,你需要阻止默认行为 `event.preventDefault()` 并且 +调用 `callback(true)`。 ```javascript session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { - // Verification logic. + // 验证逻辑。 event.preventDefault(); callback(true); } else { @@ -153,37 +154,37 @@ session.on('certificate-error', function(event, webContents, url, error, certifi }); ``` -### 事件: 'select-client-certificate' +### 事件:'select-client-certificate' 返回: -* `event` 事件 -* `webContents` [web组件](web-contents.md) -* `url` 字符串 -* `certificateList` 对象 - * `data` PEM 编码数据 - * `issuerName` 发行者的公有名称 -* `callback` 函数 +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `url` String - URL 地址 +* `certificateList` [Object] + * `data` Buffer - PEM 编码数据 + * `issuerName` String - 发行者的公有名称 +* `callback` Function 当一个客户端认证被请求的时候被触发。 -The `url` corresponds to the navigation entry requesting the client certificate -and `callback` needs to be called with an entry filtered from the list. -Using `event.preventDefault()` prevents the application from using the first -certificate from the store. +`url` 指的是请求客户端认证的网页地址,调用 `callback` 时需要传入一个证书列表中的证书。 + +需要通过调用 `event.preventDefault()` 来防止应用自动使用第一个证书进行验证。如下所示: + ```javascript app.on('select-certificate', function(event, host, url, list, callback) { event.preventDefault(); callback(list[0]); }) ``` -### Event: 'login' +### 事件: 'login' -Returns: +返回: * `event` Event -* `webContents` [Web组件](web-contents.md) +* `webContents` [WebContents](web-contents.md) * `request` Object * `method` String * `url` URL @@ -196,11 +197,10 @@ Returns: * `realm` String * `callback` Function -当 `webContents` 要做验证时被触发。 +当 `webContents` 要做进行一次 HTTP 登陆验证时被触发。 -The default behavior is to cancel all authentications, to override this you -should prevent the default behavior with `event.preventDefault()` and call -`callback(username, password)` with the credentials. +默认情况下,Electron 会取消所有的验证行为,如果需要重写这个行为,你需要用 `event.preventDefault()` 来阻止默认行为,并且 +用 `callback(username, password)` 来进行验证。 ```javascript app.on('login', function(event, webContents, request, authInfo, callback) { @@ -208,22 +208,22 @@ app.on('login', function(event, webContents, request, authInfo, callback) { callback('username', 'secret'); }) ``` -### 事件: 'gpu-process-crashed' +### 事件:'gpu-process-crashed' -当GPU进程崩溃时触发。 +当 GPU 进程崩溃时触发。 -## 方法 +## 方法列表 `app` 对象拥有以下的方法: -**提示:** 有的方法只能用于特定的操作系统。 +**请注意** 有的方法只能用于特定的操作系统。 ### `app.quit()` -试图关掉所有的窗口。`before-quit` 事件将会被最先触发。如果所有的窗口都被成功关闭了, +试图关掉所有的窗口。`before-quit` 事件将会最先被触发。如果所有的窗口都被成功关闭了, `will-quit` 事件将会被触发,默认下应用将会被关闭。 -这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。会存在一个窗口被 `beforeunload` 事件处理器返回 `false` 取消退出的可能性。 +这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。假如一个窗口的 `beforeunload` 事件处理器返回 `false`,那么整个应用可能会取消退出。 ### `app.hide()` _OS X_ @@ -241,30 +241,29 @@ app.on('login', function(event, webContents, request, authInfo, callback) { 所有的窗口会被立刻关闭,不会询问用户。`before-quit` 和 `will-quit` 这2个事件不会被触发 - ### `app.getAppPath()` 返回当前应用所在的文件路径。 ### `app.getPath(name)` -* `name` 字符串 +* `name` String 返回一个与 `name` 参数相关的特殊文件夹或文件路径。当失败时抛出一个 `Error` 。 你可以通过名称请求以下的路径: -* `home` 用户的 home 文件夹。 -* `appData` 所有用户的应用数据文件夹,默认对应: +* `home` 用户的 home 文件夹(主目录) +* `appData` 当前用户的应用数据文件夹,默认对应: * `%APPDATA%` Windows 中 * `$XDG_CONFIG_HOME` or `~/.config` Linux 中 * `~/Library/Application Support` OS X 中 -* `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称。 -* `temp` 临时文件夹。 +* `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称 +* `temp` 临时文件夹 * `exe` 当前的可执行文件 -* `module` `libchromiumcontent` 库. -* `desktop` 当前用户的桌面文件夹。 -* `documents` "我的文件夹"的路径. +* `module` `libchromiumcontent` 库 +* `desktop` 当前用户的桌面文件夹 +* `documents` 用户文档目录的路径 * `downloads` 用户下载目录的路径. * `music` 用户音乐目录的路径. * `pictures` 用户图片目录的路径. @@ -272,14 +271,14 @@ app.on('login', function(event, webContents, request, authInfo, callback) { ### `app.setPath(name, path)` -* `name` 字符串 -* `path` 字符串 +* `name` String +* `path` String -重写 `path` 参数到一个特别的文件夹或者是一个和 `name` 参数有关系的文件。 +重写某个 `name` 的路径为 `path`,`path` 可以是一个文件夹或者一个文件,这个和 `name` 的类型有关。 如果这个路径指向的文件夹不存在,这个文件夹将会被这个方法创建。 -如果错误则抛出 `Error` 。 +如果错误则会抛出 `Error`。 -你只可以指向 `app.getPath` 中定义过 `name` 的路径。 +`name` 参数只能使用 `app.getPath` 中定义过 `name`。 默认情况下,网页的 cookie 和缓存都会储存在 `userData` 文件夹。 如果你想要改变这个位置,你需要在 `app` 模块中的 `ready` 事件被触发之前重写 `userData` 的路径。 @@ -293,22 +292,20 @@ app.on('login', function(event, webContents, request, authInfo, callback) { 返回当前应用程序的 `package.json` 文件中的名称。 -通常 `name` 字段是一个短的小写字符串,其命名规则按照 npm 中的模块命名规则。你应该单独列举一个 -`productName` 字段,用于表示你的应用程序的完整名称,这个名称将会被 Electron 优先采用。 +由于 npm 的命名规则,通常 `name` 字段是一个短的小写字符串。但是应用名的完整名称通常是首字母大写的,你应该单独使用一个 +`productName` 字段,用于表示你的应用程序的完整名称。Electron 会优先使用这个字段作为应用名。 ### `app.getLocale()` -返回当前应用程序的语言种类。 - - +返回当前应用程序的语言。 ### `app.addRecentDocument(path)` _OS X_ _Windows_ -* `path` 字符串 +* `path` String -为最近访问的文档列表中添加 `path` 。 +在最近访问的文档列表中添加 `path`。 -这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过dock 菜单进行访问。 +这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过 dock 菜单进行访问。 ### `app.clearRecentDocuments()` _OS X_ _Windows_ @@ -316,66 +313,55 @@ app.on('login', function(event, webContents, request, authInfo, callback) { ### `app.setUserTasks(tasks)` _Windows_ -* `tasks` 由 `Task` 对象构成的数组 +* `tasks` [Task] - 一个由 Task 对象构成的数组 将 `tasks` 添加到 Windows 中 JumpList 功能的 [Tasks][tasks] 分类中。 `tasks` 中的 `Task` 对象格式如下: -`Task` 对象 -* `program` 字符串 - 执行程序的路径,通常你应该说明当前程序的路径为 `process.execPath` 字段。 -* `arguments` 字符串 - 当 `program` 执行时的命令行参数。 -* `title` 字符串 - JumpList 中显示的标题。 -* `description` 字符串 - 对这个任务的描述。 -* `iconPath` 字符串 - JumpList 中显示的 icon 的绝对路径,可以是一个任意包含一个icon的资源文件。你通常可以通过指明 `process.execPath` 来显示程序中的icon。 -* `iconIndex` 整数 - icon文件中的icon目录。如果一个icon文件包括了两个或多个icon,就需要设置这个值以确定icon。如果一个文件仅包含一个icon,那么这个值为0。 +`Task` Object +* `program` String - 执行程序的路径,通常你应该说明当前程序的路径为 `process.execPath` 字段。 +* `arguments` String - 当 `program` 执行时的命令行参数。 +* `title` String - JumpList 中显示的标题。 +* `description` String - 对这个任务的描述。 +* `iconPath` String - JumpList 中显示的图标的绝对路径,可以是一个任意包含一个图标的资源文件。通常来说,你可以通过指明 `process.execPath` 来显示程序中的图标。 +* `iconIndex` Integer - 图标文件中的采用的图标位置。如果一个图标文件包括了多个图标,就需要设置这个值以确定使用的是哪一个图标。 +如果这个图标文件中只包含一个图标,那么这个值为 0。 ### `app.allowNTLMCredentialsForAllDomains(allow)` * `allow` Boolean -Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate -authentication - normally, Electron will only send NTLM/Kerberos credentials for -URLs that fall under "Local Intranet" sites (i.e. are in the same domain as you). -However, this detection often fails when corporate networks are badly configured, -so this lets you co-opt this behavior and enable it for all URLs. +动态设置是否总是为 HTTP NTLM 或 Negotiate 认证发送证书。通常来说,Electron 只会对本地网络(比如和你处在一个域中的计算机)发 +送 NTLM / Kerberos 证书。但是假如网络设置得不太好,可能这个自动探测会失效,所以你可以通过这个接口自定义 Electron 对所有 URL +的行为。 + ### `app.makeSingleInstance(callback)` * `callback` Function -This method makes your application a Single Instance Application - instead of -allowing multiple instances of your app to run, this will ensure that only a -single instance of your app is running, and other instances signal this -instance and exit. +这个方法可以让你的应用在同一时刻最多只会有一个实例,否则你的应用可以被运行多次并产生多个实例。你可以利用这个接口保证只有一个实例正 +常运行,其余的实例全部会被终止并退出。 -`callback` will be called with `callback(argv, workingDirectory)` when a second -instance has been executed. `argv` is an Array of the second instance's command -line arguments, and `workingDirectory` is its current working directory. Usually -applications respond to this by making their primary window focused and -non-minimized. +如果多个实例同时运行,那么第一个被运行的实例中 `callback` 会以 `callback(argv, workingDirectory)` 的形式被调用。其余的实例 +会被终止。 +`argv` 是一个包含了这个实例的命令行参数列表的数组,`workingDirectory` 是这个实例目前的运行目录。通常来说,我们会用通过将应用在 +主屏幕上激活,并且取消最小化,来提醒用户这个应用已经被打开了。 -The `callback` is guaranteed to be executed after the `ready` event of `app` -gets emitted. +在 `app` 的 `ready` 事件后,`callback` 才有可能被调用。 -This method returns `false` if your process is the primary instance of the -application and your app should continue loading. And returns `true` if your -process has sent its parameters to another instance, and you should immediately -quit. +如果当前实例为第一个实例,那么在这个方法将会返回 `false` 来保证它继续运行。否则将会返回 `true` 来让它立刻退出。 -On OS X the system enforces single instance automatically when users try to open -a second instance of your app in Finder, and the `open-file` and `open-url` -events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to -use this method to ensure single instance. +在 OS X 中,如果用户通过 Finder、`open-file` 或者 `open-url` 打开应用,系统会强制确保只有一个实例在运行。但是如果用户是通过 +命令行打开,这个系统机制会被忽略,所以你仍然需要靠这个方法来保证应用为单实例运行的。 -An example of activating the window of primary instance when a second instance -starts: +下面是一个简单的例子。我们可以通过这个例子了解如何确保应用为单实例运行状态。 ```js var myWindow = null; var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { - // Someone tried to run a second instance, we should focus our window. + // 当另一个实例运行的时候,这里将会被调用,我们需要激活应用的窗口 if (myWindow) { if (myWindow.isMinimized()) myWindow.restore(); myWindow.focus(); @@ -383,104 +369,109 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) return true; }); +// 这个实例是多余的实例,需要退出 if (shouldQuit) { app.quit(); return; } -// Create myWindow, load the rest of the app, etc... +// 创建窗口、继续加载应用、应用逻辑等…… app.on('ready', function() { }); + ``` ### `app.setAppUserModelId(id)` _Windows_ * `id` String -改变 [Application User Model ID][app-user-model-id] 的 `id`. +改变当前应用的 [Application User Model ID][app-user-model-id] 为 `id`. ### `app.isAeroGlassEnabled()` _Windows_ -This method returns `true` if [DWM composition](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx) -(Aero Glass) is enabled, and `false` otherwise. You can use it to determine if -you should create a transparent window or not (transparent windows won't work -correctly when DWM composition is disabled). +如果 [DWM composition](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx)(Aero Glass) 启用 +了,那么这个方法会返回 `true`,否则是 `false`。你可以用这个方法来决定是否要开启透明窗口特效,因为如果用户没开启 DWM,那么透明窗 +口特效是无效的。 -Usage example: +举个例子: ```js let browserOptions = {width: 1000, height: 800}; -// Make the window transparent only if the platform supports it. +// 只有平台支持的时候才使用透明窗口 if (process.platform !== 'win32' || app.isAeroGlassEnabled()) { browserOptions.transparent = true; browserOptions.frame = false; } -// Create the window. +// 创建窗口 win = new BrowserWindow(browserOptions); -// Navigate. +// 转到某个网页 if (browserOptions.transparent) { win.loadURL('file://' + __dirname + '/index.html'); } else { - // No transparency, so we load a fallback that uses basic styles. + // 没有透明特效,我们应该用某个只包含基本样式的替代解决方案。 win.loadURL('file://' + __dirname + '/fallback.html'); } ``` ### `app.commandLine.appendSwitch(switch[, value])` -通过可选的参数 `value` 给 Chromium 命令行中添加一个开关。 -Append a switch (with optional `value`) to Chromium's command line. +通过可选的参数 `value` 给 Chromium 中添加一个命令行开关。 -**贴士:** 这不会影响 `process.argv` ,这个方法主要被开发者用于控制一些低层级的 Chromium 行为。 +**注意** 这个方法不会影响 `process.argv`,我们通常用这个方法控制一些底层 Chromium 行为。 ### `app.commandLine.appendArgument(value)` -给 Chromium 命令行中加入一个参数。这个参数是当前正在被引用的。 +给 Chromium 中直接添加一个命令行参数,这个参数 `value` 的引号和格式必须正确。 -**贴士:** 这不会影响 `process.argv`。 +**注意** 这个方法不会影响 `process.argv`。 ### `app.dock.bounce([type])` _OS X_ -* `type` 字符串 (可选的) - 可以是 `critical` 或 `informational`。默认下是 `informational` +* `type` String - 可选参数,可以是 `critical` 或 `informational`。默认为 `informational`。 -当输入 `critical` 时,dock 中的 icon 将会开始弹跳直到应用被激活或者这个请求被取消。 +当传入的是 `critical` 时,dock 中的应用将会开始弹跳,直到这个应用被激活或者这个请求被取消。 -当输入 `informational` 时,dock 中的 icon 只会弹跳一秒钟。 -然而,这个请求仍然会激活,直到应用被激活或者请求被取消。 +当传入的是 `informational` 时,dock 中的图标只会弹跳一秒钟。但是,这个请求仍然会激活,直到应用被激活或者请求被取消。 -返回一个表示这个请求的 ID。 +这个方法返回的返回值表示这个请求的 ID。 ### `app.dock.cancelBounce(id)` _OS X_ -* `id` 整数 +* `id` Integer 取消这个 `id` 对应的请求。 ### `app.dock.setBadge(text)` _OS X_ -* `text` 字符串 +* `text` String -设置 dock 中显示的字符。 +设置应用在 dock 中显示的字符串。 ### `app.dock.getBadge()` _OS X_ -返回 dock 中显示的字符。 +返回应用在 dock 中显示的字符串。 ### `app.dock.hide()` _OS X_ -隐藏 dock 中的 icon。 +隐藏应用在 dock 中的图标。 ### `app.dock.show()` _OS X_ -显示 dock 中的 icon。 +显示应用在 dock 中的图标。 ### `app.dock.setMenu(menu)` _OS X_ -* `menu` 菜单 +* `menu` [Menu](menu.md) 设置应用的 [dock 菜单][dock-menu]. +### `app.dock.setIcon(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +设置应用在 dock 中显示的图标。 + [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 a05e98f4638909bf1557755a0d9838d4988328b9 Mon Sep 17 00:00:00 2001 From: Magica Date: Sun, 21 Feb 2016 14:09:34 +0800 Subject: [PATCH 110/132] Translate auto-updater.md in commit 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/auto-updater.md | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs-translations/zh-CN/api/auto-updater.md diff --git a/docs-translations/zh-CN/api/auto-updater.md b/docs-translations/zh-CN/api/auto-updater.md new file mode 100644 index 000000000000..f027fbc6e503 --- /dev/null +++ b/docs-translations/zh-CN/api/auto-updater.md @@ -0,0 +1,88 @@ +# autoUpdater + +这个模块提供了一个到 `Squirrel` 自动更新框架的接口。 + +## 平台相关的提示 + +虽然 `autoUpdater` 模块提供了一套各平台通用的接口,但是在每个平台间依然会有一些微小的差异。 + +### OS X + +在 OS X 上,`autoUpdater` 模块依靠的是内置的 [Squirrel.Mac][squirrel-mac],这意味着你不需要依靠其他的设置就能使用。关于 +更新服务器的配置,你可以通过阅读 [Server Support][server-support] 这篇文章来了解。 + +### Windows + +在 Windows 上,你必须使用安装程序将你的应用装到用户的计算机上,所以比较推荐的方法是用 [grunt-electron-installer][installer] 这个模块来自动生成一个 Windows 安装向导。 + +Squirrel 自动生成的安装向导会生成一个带 [Application User Model ID][app-user-model-id] 的快捷方式。 +Application User Model ID 的格式是 `com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, 比如 +像 `com.squirrel.slack.Slack` 和 `com.squirrel.code.Code` 这样的。你应该在自己的应用中使用 `app.setAppUserModelId` 方法设置相同的 API,不然 Windows 将不能正确地把你的应用固定在任务栏上。 + +服务器端的配置和 OS X 也是不一样的,你可以阅读 [Squirrel.Windows][squirrel-windows] 这个文档来获得详细信息。 + +### Linux + +Linux 下没有任何的自动更新支持,所以我们推荐用各个 Linux 发行版的包管理器来分发你的应用。 + +## 事件列表 + +`autoUpdater` 对象会触发以下的事件: + +### 事件:'error' + +返回: + +* `error` Error + +当更新发生错误的时候触发。 + +### 事件:'checking-for-update' + +当开始检查更新的时候触发。 + +### 事件:'update-available' + +当发现一个可用更新的时候触发,更新包下载会自动开始。 + +### 事件:'update-not-available' + +当没有可用更新的时候触发。 + +### 事件:'update-downloaded' + +返回: + +* `event` Event +* `releaseNotes` String - 新版本更新公告 +* `releaseName` String - 新的版本号 +* `releaseDate` Date - 新版本发布的日期 +* `updateURL` String - 更新地址 + +在更新下载完成的时候触发。 + +在 Windows 上只有 `releaseName` 是有效的。 + +## 方法列表 + +`autoUpdater` 对象有以下的方法: + +### `autoUpdater.setFeedURL(url)` + +* `url` String + +设置检查更新的 `url`,并且初始化自动更新。这个 `url` 一旦设置就无法更改。 + +### `autoUpdater.checkForUpdates()` + +向服务端查询现在是否有可用的更新。在调用这个方法之前,必须要先调用 `setFeedURL`。 + +### `autoUpdater.quitAndInstall()` + +在下载完成后,重启当前的应用并且安装更新。这个方法应该仅在 `update-downloaded` 事件触发后被调用。 + +[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 078c7bf8ab2293ebb1a5b0bde489a5f6da42c443 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Sun, 21 Feb 2016 00:14:34 -0800 Subject: [PATCH 111/132] Rename constant `PERSIST_PERFIX` to `PERSIST_PREFIX` in `session.js`. --- atom/browser/api/lib/session.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/lib/session.js b/atom/browser/api/lib/session.js index dc65264349fa..8662759192dd 100644 --- a/atom/browser/api/lib/session.js +++ b/atom/browser/api/lib/session.js @@ -1,6 +1,6 @@ const EventEmitter = require('events').EventEmitter; const bindings = process.atomBinding('session'); -const PERSIST_PERFIX = 'persist:'; +const PERSIST_PREFIX = 'persist:'; // Returns the Session from |partition| string. exports.fromPartition = function(partition) { @@ -10,8 +10,8 @@ exports.fromPartition = function(partition) { if (partition === '') { return exports.defaultSession; } - if (partition.startsWith(PERSIST_PERFIX)) { - return bindings.fromPartition(partition.substr(PERSIST_PERFIX.length), false); + if (partition.startsWith(PERSIST_PREFIX)) { + return bindings.fromPartition(partition.substr(PERSIST_PREFIX.length), false); } else { return bindings.fromPartition(partition, true); } From f63532fa9558dc435764ea8b94f4acdb38ae8469 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 19 Feb 2016 09:39:43 +0900 Subject: [PATCH 112/132] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 89cc17322637..048026e0d599 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -164,7 +164,7 @@ Returns: 기본 동작을 방지하고 인증을 승인할 수 있습니다. ```javascript -session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { +app.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { // Verification logic. event.preventDefault(); diff --git a/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md b/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md index d729c0efc08b..b9fec886769d 100644 --- a/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md +++ b/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md @@ -8,6 +8,10 @@ Electron은 라이센스상의 문제로 Widevine CDM 플러그인을 직접 제 따라서 플러그인을 얻으려면 먼저 사용할 Electron 빌드의 아키텍쳐와 버전에 맞춰 공식 Chrome 브라우저를 설치해야 합니다. +__참고:__ Chrome 브라우저의 메이저 버전은 Electron에서 사용하는 Chrome 버전과 +같습니다, 만약 그렇지 않다면 `navigator.plugins`가 로드됐더라도 정상적으로 작동하지 +않습니다. + ### Windows & OS X Chrome 브라우저에서 `chrome://components/`를 열고 `WidevineCdm`을 찾은 후 확실히 From 9e1da8f097bf22b3cef4d0a4d4b3dee1c179d428 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Mon, 22 Feb 2016 00:59:18 +0900 Subject: [PATCH 113/132] Update as upstream --- docs-translations/jp/faq/electron-faq.md | 25 +++++++++++++++ .../desktop-environment-integration.md | 32 +++++++++++++++---- docs-translations/jp/tutorial/quick-start.md | 4 +++ .../tutorial/using-selenium-and-webdriver.md | 2 +- .../jp/tutorial/using-widevine-cdm-plugin.md | 2 ++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/docs-translations/jp/faq/electron-faq.md b/docs-translations/jp/faq/electron-faq.md index c8a652277174..eef30c013a3f 100644 --- a/docs-translations/jp/faq/electron-faq.md +++ b/docs-translations/jp/faq/electron-faq.md @@ -12,6 +12,27 @@ Node.js の新しいバージョンがリリースされたとき、私たちは 通常、Node.js の新しい機能は V8 のアップグレードによってもたらされますが、Electron は Chrome ブラウザーに搭載されている V8 を使用しているので、新しい Node.js に入ったばかりのピカピカに新しい JavaScript 機能は Electron ではたいてい既に導入されています。 +## ウェブページ間のデータを共有する方法は? + +ウェブページ(レンダラープロセス)間のデータを共有するために最も単純な方法は、ブラウザで、すでに提供されているHTML5 APIを使用することです。もっとも良い方法は、[Storage API][storage]、[`localStorage`][local-storage]、[`sessionStorage`][session-storage]、[IndexedDB][indexed-db]です。 + +```javascript +// In the main process. +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// In page 1. +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// In page 2. +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + ## 何分か経つと、アプリの Window/tray が消えてしまいます これは、Window/trayを格納するのに使用している変数がガベージコレクトされたときに発生します。 @@ -104,3 +125,7 @@ npm uninstall -g electron [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs-translations/jp/tutorial/desktop-environment-integration.md b/docs-translations/jp/tutorial/desktop-environment-integration.md index 0ef44b2f47c7..96bf76d73709 100644 --- a/docs-translations/jp/tutorial/desktop-environment-integration.md +++ b/docs-translations/jp/tutorial/desktop-environment-integration.md @@ -210,6 +210,23 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## タスクバーでアイコンをオーバーレイする (Windows) + +Windowsで、タスクバーボタンはアプリケーションステータスを表示するために小さなオーバーレイを使うことができます。MSDNから引用します。 + +> アイコン オーバーレイは、状況に応じた状態通知として機能し、通知領域に状態アイコンを個別に表示する必要性をなくして、情報をユーザーに伝えることを目的としています。たとえば、現在、通知領域に表示される Microsoft Office Outlook の新着メールの通知は、タスク バー ボタンのオーバーレイとして表示できるようになります。ここでも、開発サイクルの間に、アプリケーションに最適な方法を決定する必要があります。アイコン オーバーレイは、重要で長期にわたる状態や通知 (ネットワークの状態、メッセンジャーの状態、新着メールなど) を提供することを目的としています。ユーザーに対して、絶えず変化するオーバーレイやアニメーションを表示しないようにしてください。 + +__タスクバーボタンでのオーバーレイ:__ + +![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +ウィンドウでオーバーレイアイコンを設定するために、[BrowserWindow.setOverlayIcon][setoverlayicon] APIを使用できます。 + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## Windowのファイル表示 (OS X) OS Xでは、ウィンドウがrepresented fileを設定でき、タイトルバー上にファイルのアイコンを表示でき、タイトル上でCommand-クリックまたはControl-クリックをすると、パスがポップアップ表示されます。 @@ -228,15 +245,16 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 [tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx [notification-spec]: https://developer.gnome.org/notification-spec/ diff --git a/docs-translations/jp/tutorial/quick-start.md b/docs-translations/jp/tutorial/quick-start.md index bfb6e2a51f76..4f2e5c9a52ef 100644 --- a/docs-translations/jp/tutorial/quick-start.md +++ b/docs-translations/jp/tutorial/quick-start.md @@ -24,6 +24,8 @@ Electron はウェブページを表示させるために Chromium を使用し Electron では、メインプロセスとレンダラープロセスとのコミュニケーションをするために [ipc](../api/ipc-renderer.md) モジュールを提供しています。またそれと、RPC 形式の通信を行う [remote](../api/remote.md) モジュールもあります。 +Electron では、メインプロセスとレンダラープロセスとのコミュニケーションをするには幾つかのほうほうがあります。メッセージを送信する[`ipcRenderer`](../api/ipc-renderer.md)モジュールと[`ipcMain`](../api/ipc-main.md)モジュールのように、RPC 形式の通信を行う[remote](../api/remote.md)モジュールです。[ウェブページ間のデータを共有する方法][share-data]にFAQエントリーがあります。 + ## Electronアプリを作成する 一般的に Electron アプリの構成は次のようになります: @@ -169,3 +171,5 @@ $ cd electron-quick-start # Install dependencies and run the app $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#how-to-share-data-between-web-pages diff --git a/docs-translations/jp/tutorial/using-selenium-and-webdriver.md b/docs-translations/jp/tutorial/using-selenium-and-webdriver.md index 3202028ebf5f..a1fd0f21d7f9 100644 --- a/docs-translations/jp/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/jp/tutorial/using-selenium-and-webdriver.md @@ -41,7 +41,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // Here is the path to your Electron binary. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') diff --git a/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md b/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md index 5cee7f26dc66..55f9d039f611 100644 --- a/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md +++ b/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md @@ -6,6 +6,8 @@ Electronで、Chromeブラウザーに同梱される Widevine CDMプラグイ Electronは、ライセンス的な理由でWidevine CDMプラグインは同梱されません。Widevine CDMプラグインを取得するために、最初に、使用するElectronビルドのChromバージョンとアーキテクチャを合わせた公式のChromeブラウザーをインストールする必要があります。 +__Note:__ Chromeブラウザの主要バージョンは、Electronが使用するChromeバージョンと同じでなければなりません。そうでなければ、プラグインは、`navigator.plugins`経由でロードされて表示されるにも関わらず動作しません。 + ### Windows & OS X Chromeブラウザーで、`chrome://components/`を開き、 `WidevineCdm` を探し、それが最新であることを確認し、`APP_DATA/Google/Chrome/WidevineCDM/VERSION/_platform_specific/PLATFORM_ARCH/`ディレクトリからすべてのプラグインバイナリを探します。 From 67324ce732f7cf88d4850f1584d048387bb8385b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 10:52:21 +0800 Subject: [PATCH 114/132] Keep the prototype chain in remote objects --- atom/browser/lib/rpc-server.js | 57 ++++++++--- atom/renderer/api/lib/remote.js | 173 +++++++++++++++----------------- 2 files changed, 127 insertions(+), 103 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 976a42331b6a..64785879b3f2 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -6,11 +6,52 @@ const objectsRegistry = require('./objects-registry'); const v8Util = process.atomBinding('v8_util'); const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap; +// The internal properties of Function. +const FUNCTION_PROPERTIES = [ + 'length', 'name', 'arguments', 'caller', 'prototype', +]; + var slice = [].slice; +// Return the description of object's members: +let getObjectMemebers = function(object) { + let names = Object.getOwnPropertyNames(object); + // For Function, we should not override following properties even though they + // are "own" properties. + if (typeof object === 'function') { + names = names.filter((name) => { + return !FUNCTION_PROPERTIES.includes(name); + }); + } + // Map properties to descriptors. + return names.map((name) => { + let descriptor = Object.getOwnPropertyDescriptor(object, name); + let member = {name, enumerable: descriptor.enumerable, writable: false}; + if (descriptor.get === undefined && typeof object[name] === 'function') { + member.type = 'method'; + } else { + if (descriptor.set || descriptor.writable) + member.writable = true; + member.type = 'get'; + } + return member; + }); +}; + +// Return the description of object's prototype. +let getObjectPrototype = function(object) { + let proto = Object.getPrototypeOf(object); + if (proto === null || proto === Object.prototype) + return null; + return { + members: getObjectMemebers(proto), + proto: getObjectPrototype(proto), + }; +}; + // Convert a real value into meta data. var valueToMeta = function(sender, value, optimizeSimpleObject) { - var el, field, i, len, meta, name; + var el, i, len, meta; if (optimizeSimpleObject == null) { optimizeSimpleObject = false; } @@ -58,18 +99,8 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { // passed to renderer we would assume the renderer keeps a reference of // it. meta.id = objectsRegistry.add(sender.getId(), value); - meta.members = (function() { - var results; - results = []; - for (name in value) { - field = value[name]; - results.push({ - name: name, - type: typeof field - }); - } - return results; - })(); + meta.members = getObjectMemebers(value); + meta.proto = getObjectPrototype(value); } else if (meta.type === 'buffer') { meta.value = Array.prototype.slice.call(value, 0); } else if (meta.type === 'promise') { diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index d8a5508621e0..d28ec6dfcbd0 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcRenderer = require('electron').ipcRenderer; const CallbacksRegistry = require('electron').CallbacksRegistry; const v8Util = process.atomBinding('v8_util'); @@ -88,9 +90,59 @@ var wrapArgs = function(args, visited) { return Array.prototype.slice.call(args).map(valueToMeta); }; +// Populate object's members from descriptors. +// This matches |getObjectMemebers| in rpc-server. +let setObjectMembers = function(object, metaId, members) { + for (let member of members) { + if (object.hasOwnProperty(member.name)) + continue; + + let descriptor = { enumerable: member.enumerable }; + if (member.type === 'method') { + let remoteMemberFunction = function() { + if (this && this.constructor === remoteMemberFunction) { + // Constructor call. + let ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(arguments)); + return metaToValue(ret); + } else { + // Call member function. + let ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(arguments)); + return metaToValue(ret); + } + }; + descriptor.value = remoteMemberFunction; + } else if (member.type === 'get') { + descriptor.get = function() { + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_GET', metaId, member.name)); + }; + + // Only set setter when it is writable. + if (member.writable) { + descriptor.set = function(value) { + ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_SET', metaId, member.name, value); + return value; + }; + } + } + + Object.defineProperty(object, member.name, descriptor); + } +}; + +// Populate object's prototype from descriptor. +// This matches |getObjectPrototype| in rpc-server. +let setObjectPrototype = function(object, metaId, descriptor) { + if (descriptor === null) + return; + let proto = {}; + setObjectMembers(proto, metaId, descriptor.members); + setObjectPrototype(proto, metaId, descriptor.proto); + Object.setPrototypeOf(object, proto); +}; + // Convert meta data from browser into real value. var metaToValue = function(meta) { - var el, i, j, len, len1, member, ref1, ref2, results, ret; + var el, i, len, ref1, results, ret; switch (meta.type) { case 'value': return meta.value; @@ -115,55 +167,42 @@ var metaToValue = function(meta) { case 'exception': throw new Error(meta.message + "\n" + meta.stack); default: - if (meta.type === 'function') { - // A shadow class to represent the remote function object. - ret = (function() { - function RemoteFunction() { - var obj; - if (this.constructor === RemoteFunction) { - - // Constructor call. - obj = ipcRenderer.sendSync('ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)); - - /* - Returning object in constructor will replace constructed object - with the returned object. - http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this - */ - return metaToValue(obj); - } else { - - // Function call. - obj = ipcRenderer.sendSync('ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)); - return metaToValue(obj); - } - } - - return RemoteFunction; - - })(); - } else { - ret = v8Util.createObjectWithName(meta.name); - } - - // Polulate delegate members. - ref2 = meta.members; - for (j = 0, len1 = ref2.length; j < len1; j++) { - member = ref2[j]; - if (member.type === 'function') { - ret[member.name] = createRemoteMemberFunction(meta.id, member.name); - } else { - Object.defineProperty(ret, member.name, createRemoteMemberProperty(meta.id, member.name)); - } - } - if (remoteObjectCache.has(meta.id)) return remoteObjectCache.get(meta.id); + if (meta.type === 'function') { + // A shadow class to represent the remote function object. + let remoteFunction = function() { + if (this && this.constructor === remoteFunction) { + // Constructor call. + let obj = ipcRenderer.sendSync('ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)); + // Returning object in constructor will replace constructed object + // with the returned object. + // http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this + return metaToValue(obj); + } else { + // Function call. + let obj = ipcRenderer.sendSync('ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)); + return metaToValue(obj); + } + }; + ret = remoteFunction; + } else { + ret = {}; + } + + // Populate delegate members. + setObjectMembers(ret, meta.id, meta.members); + // Populate delegate prototype. + setObjectPrototype(ret, meta.id, meta.proto); + + // Set constructor.name to object's name. + Object.defineProperty(ret.constructor, 'name', { value: meta.name }); + // Track delegate object's life time, and tell the browser to clean up // when the object is GCed. v8Util.setDestructor(ret, function() { - return ipcRenderer.send('ATOM_BROWSER_DEREFERENCE', meta.id); + ipcRenderer.send('ATOM_BROWSER_DEREFERENCE', meta.id); }); // Remember object's id. @@ -192,52 +231,6 @@ var metaToPlainObject = function(meta) { return obj; }; -// Create a RemoteMemberFunction instance. -// This function's content should not be inlined into metaToValue, otherwise V8 -// may consider it circular reference. -var createRemoteMemberFunction = function(metaId, name) { - return (function() { - function RemoteMemberFunction() { - var ret; - if (this.constructor === RemoteMemberFunction) { - - // Constructor call. - ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CONSTRUCTOR', metaId, name, wrapArgs(arguments)); - return metaToValue(ret); - } else { - - // Call member function. - ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CALL', metaId, name, wrapArgs(arguments)); - return metaToValue(ret); - } - } - - return RemoteMemberFunction; - - })(); -}; - -// Create configuration for defineProperty. -// This function's content should not be inlined into metaToValue, otherwise V8 -// may consider it circular reference. -var createRemoteMemberProperty = function(metaId, name) { - return { - enumerable: true, - configurable: false, - set: function(value) { - - // Set member data. - ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_SET', metaId, name, value); - return value; - }, - get: function() { - - // Get member data. - return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_GET', metaId, name)); - } - }; -}; - // Browser calls a callback in renderer. ipcRenderer.on('ATOM_RENDERER_CALLBACK', function(event, id, args) { return callbacksRegistry.apply(id, metaToValue(args)); From f610e332b3e31d9713724d701798e3f945da7311 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 12:13:26 +0800 Subject: [PATCH 115/132] spec: Tests for remote ES6 class --- spec/api-ipc-spec.js | 37 +++++++++++++++++++++++++++++++++++ spec/fixtures/module/class.js | 29 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 spec/fixtures/module/class.js diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 9cf741412b08..90e099fa612e 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -1,3 +1,5 @@ +'use strict'; + const assert = require('assert'); const path = require('path'); @@ -98,6 +100,41 @@ describe('ipc module', function() { }); }); + describe('remote class', function() { + let cl = remote.require(path.join(fixtures, 'module', 'class.js')); + let base = cl.base; + let derived = cl.derived; + + it('can get methods', function() { + assert.equal(base.method(), 'method'); + }); + + it('can get properties', function() { + assert.equal(base.readonly, 'readonly'); + }); + + it('can change properties', function() { + assert.equal(base.value, 'old'); + base.value = 'new'; + assert.equal(base.value, 'new'); + base.value = 'old'; + }); + + it('has unenumerable methods', function() { + assert(!base.hasOwnProperty('method')); + assert(Object.getPrototypeOf(base).hasOwnProperty('method')); + }); + + it('keeps prototype chain in derived class', function() { + assert.equal(derived.method(), 'method'); + assert.equal(derived.readonly, 'readonly'); + assert(!derived.hasOwnProperty('method')); + let proto = Object.getPrototypeOf(derived); + assert(!proto.hasOwnProperty('method')); + assert(Object.getPrototypeOf(proto).hasOwnProperty('method')); + }); + }); + describe('ipc.sender.send', function() { it('should work when sending an object containing id property', function(done) { var obj = { diff --git a/spec/fixtures/module/class.js b/spec/fixtures/module/class.js new file mode 100644 index 000000000000..f25eb2593ff3 --- /dev/null +++ b/spec/fixtures/module/class.js @@ -0,0 +1,29 @@ +'use strict'; + +let value = 'old'; + +class BaseClass { + method() { + return 'method'; + } + + get readonly() { + return 'readonly'; + } + + get value() { + return value; + } + + set value(val) { + value = val; + } +} + +class DerivedClass extends BaseClass { +} + +module.exports = { + base: new BaseClass, + derived: new DerivedClass, +} From c65cfadd094f951d65b5561df40c778d3ba583d6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 11:51:41 +0800 Subject: [PATCH 116/132] v8Util.createObjectWithName is no longer used --- atom/browser/lib/rpc-server.js | 4 +++- atom/common/api/atom_api_v8_util.cc | 35 ----------------------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 64785879b3f2..c3e5159cd9ef 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -162,7 +162,9 @@ var unwrapArgs = function(sender, args) { then: metaToValue(meta.then) }); case 'object': { - let ret = v8Util.createObjectWithName(meta.name); + let ret = {}; + Object.defineProperty(ret.constructor, 'name', { value: meta.name }); + ref = meta.members; for (i = 0, len = ref.length; i < len; i++) { member = ref[i]; diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index c86335adb15e..f50d3485eba6 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -2,49 +2,15 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include #include #include "atom/common/api/object_life_monitor.h" #include "atom/common/node_includes.h" -#include "base/stl_util.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" namespace { -// A Persistent that can be copied and will not free itself. -template -struct LeakedPersistentTraits { - typedef v8::Persistent > LeakedPersistent; - static const bool kResetInDestructor = false; - template - static V8_INLINE void Copy(const v8::Persistent& source, - LeakedPersistent* dest) { - // do nothing, just allow copy - } -}; - -// The handles are leaked on purpose. -using FunctionTemplateHandle = - LeakedPersistentTraits::LeakedPersistent; -std::map function_templates_; - -v8::Local CreateObjectWithName(v8::Isolate* isolate, - const std::string& name) { - if (name == "Object") - return v8::Object::New(isolate); - - if (ContainsKey(function_templates_, name)) - return v8::Local::New( - isolate, function_templates_[name])->GetFunction()->NewInstance(); - - v8::Local t = v8::FunctionTemplate::New(isolate); - t->SetClassName(mate::StringToV8(isolate, name)); - function_templates_[name] = FunctionTemplateHandle(isolate, t); - return t->GetFunction()->NewInstance(); -} - v8::Local GetHiddenValue(v8::Local object, v8::Local key) { return object->GetHiddenValue(key); @@ -78,7 +44,6 @@ void TakeHeapSnapshot(v8::Isolate* isolate) { void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); - dict.SetMethod("createObjectWithName", &CreateObjectWithName); dict.SetMethod("getHiddenValue", &GetHiddenValue); dict.SetMethod("setHiddenValue", &SetHiddenValue); dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue); From fe7462b3526d9c74534133273305223180ed0fd5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 12:26:41 +0800 Subject: [PATCH 117/132] No longer needs cache for methods of remote Refs #4517. --- atom/renderer/api/lib/remote.js | 56 +++++---------------------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index d28ec6dfcbd0..a9798338faa6 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -141,7 +141,7 @@ let setObjectPrototype = function(object, metaId, descriptor) { }; // Convert meta data from browser into real value. -var metaToValue = function(meta) { +let metaToValue = function(meta) { var el, i, len, ref1, results, ret; switch (meta.type) { case 'value': @@ -257,73 +257,33 @@ for (var name in browserModules) { } // Get remote module. -// (Just like node's require, the modules are cached permanently, note that this -// is safe leak since the object is not expected to get freed in browser) -var moduleCache = {}; - exports.require = function(module) { - var meta; - if (moduleCache[module] != null) { - return moduleCache[module]; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_REQUIRE', module); - return moduleCache[module] = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_REQUIRE', module)); }; -// Optimize require('electron'). -moduleCache.electron = exports; - // Alias to remote.require('electron').xxx. -var builtinCache = {}; - exports.getBuiltin = function(module) { - var meta; - if (builtinCache[module] != null) { - return builtinCache[module]; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_GET_BUILTIN', module); - return builtinCache[module] = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_GET_BUILTIN', module)); }; -// Get current BrowserWindow object. -var windowCache = null; - +// Get current BrowserWindow. exports.getCurrentWindow = function() { - var meta; - if (windowCache != null) { - return windowCache; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WINDOW'); - return windowCache = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WINDOW')); }; // Get current WebContents object. -var webContentsCache = null; - exports.getCurrentWebContents = function() { - var meta; - if (webContentsCache != null) { - return webContentsCache; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WEB_CONTENTS'); - return webContentsCache = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WEB_CONTENTS')); }; // Get a global object in browser. exports.getGlobal = function(name) { - var meta; - meta = ipcRenderer.sendSync('ATOM_BROWSER_GLOBAL', name); - return metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_GLOBAL', name)); }; // Get the process object in browser. -var processCache = null; - exports.__defineGetter__('process', function() { - if (processCache == null) { - processCache = exports.getGlobal('process'); - } - return processCache; + return exports.getGlobal('process'); }); // Create a funtion that will return the specifed value when called in browser. From 2b04af434937d4cde9a5b6584c19603cc586e6c3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:03:31 +0800 Subject: [PATCH 118/132] No longer need to count the references in webContents All remote objects are now cached in renderer process, so there is always only one reference to one remote object for each webContents. --- atom/browser/lib/objects-registry.js | 73 +++++++++++----------------- atom/browser/lib/rpc-server.js | 2 +- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index e9d6d365fa5b..90d1fe80e537 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -15,70 +15,57 @@ class ObjectsRegistry extends EventEmitter { this.storage = {}; // Stores the IDs of objects referenced by WebContents. - // (webContentsId) => {(id) => (count)} + // (webContentsId) => [id] this.owners = {}; } - // Register a new object, the object would be kept referenced until you release - // it explicitly. + // Register a new object and return its assigned ID. If the object is already + // registered then the already assigned ID would be returned. add(webContentsId, obj) { - var base, base1, id; - id = this.saveToStorage(obj); + // Get or assign an ID to the object. + let id = this.saveToStorage(obj); - // Remember the owner. - if ((base = this.owners)[webContentsId] == null) { - base[webContentsId] = {}; + // Add object to the set of referenced objects. + let owner = this.owners[webContentsId]; + if (!owner) + owner = this.owners[webContentsId] = new Set(); + if (!owner.has(id)) { + owner.add(id); + // Increase reference count if not referenced before. + this.storage[id].count++; } - if ((base1 = this.owners[webContentsId])[id] == null) { - base1[id] = 0; - } - this.owners[webContentsId][id]++; - - // Returns object's id return id; } // Get an object according to its ID. get(id) { - var ref; - return (ref = this.storage[id]) != null ? ref.object : void 0; + return this.storage[id].object; } // Dereference an object according to its ID. remove(webContentsId, id) { - var pointer; - this.dereference(id, 1); + // Dereference from the storage. + this.dereference(id); - // Also reduce the count in owner. - pointer = this.owners[webContentsId]; - if (pointer == null) { - return; - } - --pointer[id]; - if (pointer[id] === 0) { - return delete pointer[id]; - } + // Also remove the reference in owner. + this.owners[webContentsId].delete(id); } // Clear all references to objects refrenced by the WebContents. clear(webContentsId) { - var count, id, ref; - this.emit("clear-" + webContentsId); - if (this.owners[webContentsId] == null) { + this.emit(`clear-${webContentsId}`); + + let owner = this.owners[webContentsId]; + if (!owner) return; - } - ref = this.owners[webContentsId]; - for (id in ref) { - count = ref[id]; - this.dereference(id, count); - } - return delete this.owners[webContentsId]; + for (let id of owner) + this.dereference(id); + delete this.owners[webContentsId]; } // Private: Saves the object into storage and assigns an ID for it. saveToStorage(object) { - var id; - id = v8Util.getHiddenValue(object, 'atomId'); + let id = v8Util.getHiddenValue(object, 'atomId'); if (!id) { id = ++this.nextId; this.storage[id] = { @@ -87,18 +74,16 @@ class ObjectsRegistry extends EventEmitter { }; v8Util.setHiddenValue(object, 'atomId', id); } - ++this.storage[id].count; return id; } // Private: Dereference the object from store. - dereference(id, count) { - var pointer; - pointer = this.storage[id]; + dereference(id) { + let pointer = this.storage[id]; if (pointer == null) { return; } - pointer.count -= count; + pointer.count -= 1; if (pointer.count === 0) { v8Util.deleteHiddenValue(pointer.object, 'atomId'); return delete this.storage[id]; diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index c3e5159cd9ef..f366eb43a52b 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -145,7 +145,7 @@ var exceptionToMeta = function(error) { var unwrapArgs = function(sender, args) { var metaToValue; metaToValue = function(meta) { - var i, len, member, ref, rendererReleased, returnValue; + var i, len, member, ref, returnValue; switch (meta.type) { case 'value': return meta.value; From 59d6e7d6ef769118a7357c2a0d266223819f1459 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:10:25 +0800 Subject: [PATCH 119/132] ObjectsRegistry no longer needs to send events --- atom/browser/lib/objects-registry.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index 90d1fe80e537..9677c7fea22d 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -1,13 +1,9 @@ 'use strict'; -const EventEmitter = require('events').EventEmitter; const v8Util = process.atomBinding('v8_util'); -class ObjectsRegistry extends EventEmitter { +class ObjectsRegistry { constructor() { - super(); - - this.setMaxListeners(Number.MAX_VALUE); this.nextId = 0; // Stores all objects by ref-counting. @@ -53,8 +49,6 @@ class ObjectsRegistry extends EventEmitter { // Clear all references to objects refrenced by the WebContents. clear(webContentsId) { - this.emit(`clear-${webContentsId}`); - let owner = this.owners[webContentsId]; if (!owner) return; From d4c954870a14c90f114482e03ef4cc3b60b092bd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:15:51 +0800 Subject: [PATCH 120/132] Remove a few CoffeeScript generated junks --- atom/browser/lib/rpc-server.js | 35 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index f366eb43a52b..c3ea8ca6b094 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -11,8 +11,6 @@ const FUNCTION_PROPERTIES = [ 'length', 'name', 'arguments', 'caller', 'prototype', ]; -var slice = [].slice; - // Return the description of object's members: let getObjectMemebers = function(object) { let names = Object.getOwnPropertyNames(object); @@ -281,14 +279,13 @@ ipcMain.on('ATOM_BROWSER_CURRENT_WEB_CONTENTS', function(event) { }); ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function(event, id, args) { - var constructor, obj; try { args = unwrapArgs(event.sender, args); - constructor = objectsRegistry.get(id); + let constructor = objectsRegistry.get(id); // Call new with array of arguments. // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible - obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); return event.returnValue = valueToMeta(event.sender, obj); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -296,10 +293,9 @@ ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function(event, id, args) { }); ipcMain.on('ATOM_BROWSER_FUNCTION_CALL', function(event, id, args) { - var func; try { args = unwrapArgs(event.sender, args); - func = objectsRegistry.get(id); + let func = objectsRegistry.get(id); return callFunction(event, func, global, args); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -307,13 +303,12 @@ ipcMain.on('ATOM_BROWSER_FUNCTION_CALL', function(event, id, args) { }); ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function(event, id, method, args) { - var constructor, obj; try { args = unwrapArgs(event.sender, args); - constructor = objectsRegistry.get(id)[method]; + let constructor = objectsRegistry.get(id)[method]; // Call new with array of arguments. - obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); return event.returnValue = valueToMeta(event.sender, obj); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -321,10 +316,9 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function(event, id, method, args) }); ipcMain.on('ATOM_BROWSER_MEMBER_CALL', function(event, id, method, args) { - var obj; try { args = unwrapArgs(event.sender, args); - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); return callFunction(event, obj[method], obj, args); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -332,9 +326,8 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CALL', function(event, id, method, args) { }); ipcMain.on('ATOM_BROWSER_MEMBER_SET', function(event, id, name, value) { - var obj; try { - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); obj[name] = value; return event.returnValue = null; } catch (error) { @@ -343,9 +336,8 @@ ipcMain.on('ATOM_BROWSER_MEMBER_SET', function(event, id, name, value) { }); ipcMain.on('ATOM_BROWSER_MEMBER_GET', function(event, id, name) { - var obj; try { - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); return event.returnValue = valueToMeta(event.sender, obj[name]); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -357,21 +349,18 @@ ipcMain.on('ATOM_BROWSER_DEREFERENCE', function(event, id) { }); ipcMain.on('ATOM_BROWSER_GUEST_WEB_CONTENTS', function(event, guestInstanceId) { - var guestViewManager; try { - guestViewManager = require('./guest-view-manager'); + let guestViewManager = require('./guest-view-manager'); return event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId)); } catch (error) { return event.returnValue = exceptionToMeta(error); } }); -ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function() { - var args, event, guest, guestInstanceId, guestViewManager, method; - event = arguments[0], guestInstanceId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; +ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, guestInstanceId, method, ...args) { try { - guestViewManager = require('./guest-view-manager'); - guest = guestViewManager.getGuest(guestInstanceId); + let guestViewManager = require('./guest-view-manager'); + let guest = guestViewManager.getGuest(guestInstanceId); return guest[method].apply(guest, args); } catch (error) { return event.returnValue = exceptionToMeta(error); From 593a79ce20296f0178e6f38016039e5e12a1f77a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:36:50 +0800 Subject: [PATCH 121/132] Separate renderer functions by renderer process ID Close #4324. --- atom/browser/lib/rpc-server.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index c3ea8ca6b094..7b59648eda13 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -11,6 +11,10 @@ const FUNCTION_PROPERTIES = [ 'length', 'name', 'arguments', 'caller', 'prototype', ]; +// The remote functions in renderer processes. +// (webContentsId) => {id: Function} +let rendererFunctions = {}; + // Return the description of object's members: let getObjectMemebers = function(object) { let names = Object.getOwnPropertyNames(object); @@ -177,32 +181,30 @@ var unwrapArgs = function(sender, args) { }; case 'function': { // Cache the callbacks in renderer. - if (!sender.callbacks) { - sender.callbacks = new IDWeakMap; - sender.on('render-view-deleted', function() { - return this.callbacks.clear(); + let webContentsId = sender.getId(); + let callbacks = rendererFunctions[webContentsId]; + if (!callbacks) { + callbacks = rendererFunctions[webContentsId] = new IDWeakMap; + sender.once('render-view-deleted', function(event, id) { + callbacks.clear(); + delete rendererFunctions[id]; }); } - if (sender.callbacks.has(meta.id)) - return sender.callbacks.get(meta.id); - - // Prevent the callback from being called when its page is gone. - rendererReleased = false; - sender.once('render-view-deleted', function() { - rendererReleased = true; - }); + if (callbacks.has(meta.id)) + return callbacks.get(meta.id); let callIntoRenderer = function(...args) { - if (rendererReleased || sender.isDestroyed()) + if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) + sender.send('ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args)); + else throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`); - sender.send('ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args)); }; v8Util.setDestructor(callIntoRenderer, function() { - if (!rendererReleased && !sender.isDestroyed()) + if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) sender.send('ATOM_RENDERER_RELEASE_CALLBACK', meta.id); }); - sender.callbacks.set(meta.id, callIntoRenderer); + callbacks.set(meta.id, callIntoRenderer); return callIntoRenderer; } default: From 6753fcc1b4bae07bad8cae674770da220bf9fafb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:54:55 +0800 Subject: [PATCH 122/132] Get rid of the ATOM_BROWSER_RELEASE_RENDER_VIEW event --- atom/browser/api/atom_api_web_contents.cc | 12 +----------- atom/browser/lib/objects-registry.js | 10 ++++++++-- atom/browser/lib/rpc-server.js | 7 +------ 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a7946786c514..72443bdb815a 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -485,17 +485,7 @@ void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { } void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) { - int process_id = render_view_host->GetProcess()->GetID(); - Emit("render-view-deleted", process_id); - - // process.emit('ATOM_BROWSER_RELEASE_RENDER_VIEW', processId); - // Tell the rpc server that a render view has been deleted and we need to - // release all objects owned by it. - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); - node::Environment* env = node::Environment::GetCurrent(isolate()); - mate::EmitEvent(isolate(), env->process_object(), - "ATOM_BROWSER_RELEASE_RENDER_VIEW", process_id); + Emit("render-view-deleted", render_view_host->GetProcess()->GetID()); } void WebContents::RenderProcessGone(base::TerminationStatus status) { diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index 9677c7fea22d..c3f70c976ecb 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -17,14 +17,20 @@ class ObjectsRegistry { // Register a new object and return its assigned ID. If the object is already // registered then the already assigned ID would be returned. - add(webContentsId, obj) { + add(webContents, obj) { // Get or assign an ID to the object. let id = this.saveToStorage(obj); // Add object to the set of referenced objects. + let webContentsId = webContents.getId(); let owner = this.owners[webContentsId]; - if (!owner) + if (!owner) { owner = this.owners[webContentsId] = new Set(); + // Clear the storage when webContents is reloaded/navigated. + webContents.once('render-view-deleted', (event, id) => { + this.clear(id); + }); + } if (!owner.has(id)) { owner.add(id); // Increase reference count if not referenced before. diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 7b59648eda13..20ee8fbdeae1 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -100,7 +100,7 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { // Reference the original value if it's an object, because when it's // passed to renderer we would assume the renderer keeps a reference of // it. - meta.id = objectsRegistry.add(sender.getId(), value); + meta.id = objectsRegistry.add(sender, value); meta.members = getObjectMemebers(value); meta.proto = getObjectPrototype(value); } else if (meta.type === 'buffer') { @@ -239,11 +239,6 @@ var callFunction = function(event, func, caller, args) { } }; -// Send by BrowserWindow when its render view is deleted. -process.on('ATOM_BROWSER_RELEASE_RENDER_VIEW', function(id) { - return objectsRegistry.clear(id); -}); - ipcMain.on('ATOM_BROWSER_REQUIRE', function(event, module) { try { return event.returnValue = valueToMeta(event.sender, process.mainModule.require(module)); From 96b2705bd3ec3fe7a92bc27bf061613d4871ae19 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 15:20:23 +0800 Subject: [PATCH 123/132] Fix render-view-deleted being emitted twice --- atom/browser/api/atom_api_web_contents.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 72443bdb815a..ee6ad94ba77a 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -296,6 +296,7 @@ WebContents::~WebContents() { // The WebContentsDestroyed will not be called automatically because we // unsubscribe from webContents before destroying it. So we have to manually // call it here to make sure "destroyed" event is emitted. + RenderViewDeleted(web_contents()->GetRenderViewHost()); WebContentsDestroyed(); } } @@ -665,9 +666,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { // be destroyed on close, and WebContentsDestroyed would be called for it, so // we need to make sure the api::WebContents is also deleted. void WebContents::WebContentsDestroyed() { - // The RenderViewDeleted was not called when the WebContents is destroyed. - RenderViewDeleted(web_contents()->GetRenderViewHost()); - // This event is only for internal use, which is emitted when WebContents is // being destroyed. Emit("will-destroy"); From 331bc42d57f04648a5c92e10afdc074d69cc827e Mon Sep 17 00:00:00 2001 From: jin5354 Date: Tue, 23 Feb 2016 10:00:28 +0800 Subject: [PATCH 124/132] docs: update zh-CN doc debugging-main-process.md update zh-CN doc debugging-main-process.md to be up-to-date with English ver. --- .../zh-CN/tutorial/debugging-main-process.md | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/docs-translations/zh-CN/tutorial/debugging-main-process.md b/docs-translations/zh-CN/tutorial/debugging-main-process.md index 48f3579394e7..f971a40892fc 100644 --- a/docs-translations/zh-CN/tutorial/debugging-main-process.md +++ b/docs-translations/zh-CN/tutorial/debugging-main-process.md @@ -18,16 +18,31 @@ ## 使用 node-inspector 来调试 -__备注:__ Electron 使用 node v0.11.13 版本,目前对 node-inspector支持的不是特别好, +__备注:__ Electron 目前对 node-inspector支持的不是特别好, 如果你通过 node-inspector 的 console 来检查 `process` 对象,主进程就会崩溃。 -### 1. 开始 [node-inspector][node-inspector] 服务 +### 1. 确认你已经安装了 [node-gyp 所需工具](https://github.com/nodejs/node-gyp#installation) + +### 2. 安装 [node-inspector][node-inspector] ```bash -$ node-inspector +$ npm install node-inspector ``` -### 2. 打开 Electron 的调试模式 +### 3. 安装 `node-pre-gyp` 的一个修订版 + +```bash +$ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electron-runtime-in-find +``` + +### 4. 为 Electron 重新编译 `node-inspector` `v8` 模块(将 target 参数修改为你的 Electron 的版本号) + +```bash +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall +``` + +### 5. 打开 Electron 的调试模式 你也可以用调试参数来运行 Electron : @@ -41,7 +56,13 @@ $ electron --debug=5858 your/app $ electron --debug-brk=5858 your/app ``` -### 3. 加载调试器界面 +### 6. 使用 Electron 开启 [node-inspector][node-inspector] 服务 + +```bash +$ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin/inspector.js +``` + +### 7. 加载调试器界面 在 Chrome 中打开 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 From 23268531ae32bc0ac8e847b3bb147f7ef6ba6641 Mon Sep 17 00:00:00 2001 From: Yasunari Fujieda Date: Tue, 23 Feb 2016 15:10:38 +0900 Subject: [PATCH 125/132] docs: update jp doc ipc-renderer.md --- docs-translations/jp/api/ipc-renderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/jp/api/ipc-renderer.md b/docs-translations/jp/api/ipc-renderer.md index 5854157363f4..edbd862ffaa6 100644 --- a/docs-translations/jp/api/ipc-renderer.md +++ b/docs-translations/jp/api/ipc-renderer.md @@ -52,7 +52,7 @@ * `channel` String - イベント名 * `arg` (optional) -`channel`経由でメインプロセスに非同期にイベントを送信し、任意の引数を送信できます。 +`channel`経由でメインプロセスに同期的にイベントを送信し、任意の引数を送信できます。 メインプロセスは`ipcMain`で`channel`を受信することでハンドルし、 `event.returnValue`を設定してリプライします。 From bdfc19ad20fff7ef7490420f44aa60cd89f606d2 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 19 Feb 2016 19:46:03 +0530 Subject: [PATCH 126/132] add docs --- atom/browser/api/lib/protocol.js | 4 ---- docs/api/session.md | 22 ++++++++++++++++++++++ spec/api-protocol-spec.js | 12 +++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index caef0ad646b4..de1bdea471f4 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -19,10 +19,6 @@ var logAndThrow = function(callback, message) { } }; -protocol.fromPartition = function(partition) { - return session.fromPartition(partition).protocol; -}; - protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/docs/api/session.md b/docs/api/session.md index cc90a0b542cf..d492f3d55c50 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -523,3 +523,25 @@ The `listener` will be called with `listener(details)` when an error occurs. * `timestamp` Double * `fromCache` Boolean * `error` String - The error description. + +#### `ses.protocol` + +Returns an instance of [protocol](protocol.md) module for this session. + +```javascript +const electron = require('electron'); +const app = electron.app; +const session = electron.session; +const path = require('path'); + +app.on('ready', function() { + const protocol = session.fromPartition(partitionName).protocol; + protocol.registerFileProtocol('atom', function(request, callback) { + var url = request.url.substr(7); + callback({path: path.normalize(__dirname + '/' + url)}); + }, function (error) { + if (error) + console.error('Failed to register protocol') + }); +}); +``` diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 483155b70652..beb483e3f801 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -5,6 +5,7 @@ const qs = require('querystring'); const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; +const session = remote.require('electron').session; describe('protocol module', function() { var protocolName = 'sp'; @@ -818,7 +819,7 @@ describe('protocol module', function() { describe('protocol.fromPartition', function() { var partitionName = 'temp'; - var tempProtocol = protocol.fromPartition(partitionName); + var tempProtocol = session.fromPartition(partitionName).protocol; var w = null; beforeEach(function() { @@ -852,17 +853,18 @@ describe('protocol module', function() { if (error) { return done(error); } + protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, false); }); tempProtocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); }); }); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); }); }); }); From 49f995925c8981f4d90809d49839e05f349a9b0a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 23 Feb 2016 15:43:32 +0800 Subject: [PATCH 127/132] Notify the global menu bar when window is mapped --- atom/browser/native_window_views.cc | 15 +++++++++++++++ atom/browser/ui/views/global_menu_bar_x11.cc | 8 ++++++++ atom/browser/ui/views/global_menu_bar_x11.h | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 44df87da9fb8..97a2ee05a331 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -300,14 +300,29 @@ bool NativeWindowViews::IsFocused() { void NativeWindowViews::Show() { window_->native_widget_private()->ShowWithWindowState(GetRestoredState()); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowMapped(); +#endif } void NativeWindowViews::ShowInactive() { window_->ShowInactive(); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowMapped(); +#endif } void NativeWindowViews::Hide() { window_->Hide(); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowUnmapped(); +#endif } bool NativeWindowViews::IsVisible() { diff --git a/atom/browser/ui/views/global_menu_bar_x11.cc b/atom/browser/ui/views/global_menu_bar_x11.cc index 26279ecbe8e6..b393e3f4657d 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.cc +++ b/atom/browser/ui/views/global_menu_bar_x11.cc @@ -210,6 +210,14 @@ void GlobalMenuBarX11::InitServer(gfx::AcceleratedWidget xid) { server_ = server_new(path.c_str()); } +void GlobalMenuBarX11::OnWindowMapped() { + GlobalMenuBarRegistrarX11::GetInstance()->OnWindowMapped(xid_); +} + +void GlobalMenuBarX11::OnWindowUnmapped() { + GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid_); +} + void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model, DbusmenuMenuitem* parent) { for (int i = 0; i < model->GetItemCount(); ++i) { diff --git a/atom/browser/ui/views/global_menu_bar_x11.h b/atom/browser/ui/views/global_menu_bar_x11.h index 51147a26f922..d9e818ce3eb6 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.h +++ b/atom/browser/ui/views/global_menu_bar_x11.h @@ -46,6 +46,10 @@ class GlobalMenuBarX11 { void SetMenu(ui::MenuModel* menu_model); bool IsServerStarted() const; + // Called by NativeWindow when it show/hides. + void OnWindowMapped(); + void OnWindowUnmapped(); + private: // Creates a DbusmenuServer. void InitServer(gfx::AcceleratedWidget xid); From bb1e4c2208fe099faf9138072bdd24a019a29ba6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 24 Feb 2016 13:25:22 +0800 Subject: [PATCH 128/132] Revert "add docs" This reverts commit bdfc19ad20fff7ef7490420f44aa60cd89f606d2. --- atom/browser/api/lib/protocol.js | 4 ++++ docs/api/session.md | 22 ---------------------- spec/api-protocol-spec.js | 12 +++++------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index de1bdea471f4..caef0ad646b4 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -19,6 +19,10 @@ var logAndThrow = function(callback, message) { } }; +protocol.fromPartition = function(partition) { + return session.fromPartition(partition).protocol; +}; + protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/docs/api/session.md b/docs/api/session.md index d492f3d55c50..cc90a0b542cf 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -523,25 +523,3 @@ The `listener` will be called with `listener(details)` when an error occurs. * `timestamp` Double * `fromCache` Boolean * `error` String - The error description. - -#### `ses.protocol` - -Returns an instance of [protocol](protocol.md) module for this session. - -```javascript -const electron = require('electron'); -const app = electron.app; -const session = electron.session; -const path = require('path'); - -app.on('ready', function() { - const protocol = session.fromPartition(partitionName).protocol; - protocol.registerFileProtocol('atom', function(request, callback) { - var url = request.url.substr(7); - callback({path: path.normalize(__dirname + '/' + url)}); - }, function (error) { - if (error) - console.error('Failed to register protocol') - }); -}); -``` diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index beb483e3f801..483155b70652 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -5,7 +5,6 @@ const qs = require('querystring'); const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; -const session = remote.require('electron').session; describe('protocol module', function() { var protocolName = 'sp'; @@ -819,7 +818,7 @@ describe('protocol module', function() { describe('protocol.fromPartition', function() { var partitionName = 'temp'; - var tempProtocol = session.fromPartition(partitionName).protocol; + var tempProtocol = protocol.fromPartition(partitionName); var w = null; beforeEach(function() { @@ -853,18 +852,17 @@ describe('protocol module', function() { if (error) { return done(error); } - protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, false); }); tempProtocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); }); }); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); }); }); }); From 8ff30a2abc15059fdce79faa1576b12bd6536158 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 24 Feb 2016 13:25:30 +0800 Subject: [PATCH 129/132] Revert "protocol: respect requests from partition" This reverts commit 85800256deb7c2eb543bba8d28eb369e3521eb54. --- atom/browser/api/atom_api_protocol.cc | 70 ++++++++++++++++----------- atom/browser/api/atom_api_protocol.h | 11 ++--- atom/browser/api/atom_api_session.cc | 10 ---- atom/browser/api/atom_api_session.h | 2 - atom/browser/api/lib/protocol.js | 9 +--- atom/common/node_bindings.cc | 1 + spec/api-protocol-spec.js | 51 ------------------- 7 files changed, 49 insertions(+), 105 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 335c20e11e3b..09da9c71cadb 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -28,6 +28,33 @@ Protocol::Protocol(AtomBrowserContext* browser_context) CHECK(job_factory_); } +mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return mate::ObjectTemplateBuilder(isolate) + .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) + .SetMethod("registerServiceWorkerSchemes", + &Protocol::RegisterServiceWorkerSchemes) + .SetMethod("registerStringProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerBufferProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerFileProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerHttpProtocol", + &Protocol::RegisterProtocol) + .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) + .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) + .SetMethod("interceptStringProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptBufferProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptFileProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptHttpProtocol", + &Protocol::InterceptProtocol) + .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); +} + void Protocol::RegisterStandardSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomSchemes(schemes); @@ -126,34 +153,21 @@ mate::Handle Protocol::Create( return mate::CreateHandle(isolate, new Protocol(browser_context)); } -// static -void Protocol::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - mate::ObjectTemplateBuilder(isolate, prototype) - .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) - .SetMethod("registerServiceWorkerSchemes", - &Protocol::RegisterServiceWorkerSchemes) - .SetMethod("registerStringProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerBufferProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerHttpProtocol", - &Protocol::RegisterProtocol) - .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) - .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) - .SetMethod("interceptStringProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptBufferProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptHttpProtocol", - &Protocol::InterceptProtocol) - .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); -} - } // namespace api } // namespace atom + +namespace { + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + auto browser_context = static_cast( + atom::AtomBrowserMainParts::Get()->browser_context()); + dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context)); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize) diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 36ab46ba8231..8aef406fbc38 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -9,7 +9,6 @@ #include #include -#include "atom/browser/api/trackable_object.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "base/callback.h" #include "base/containers/scoped_ptr_hash_map.h" @@ -31,7 +30,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::TrackableObject { +class Protocol : public mate::Wrappable { public: using Handler = base::Callback)>; @@ -41,13 +40,13 @@ class Protocol : public mate::TrackableObject { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); - // mate::TrackableObject: - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); - protected: explicit Protocol(AtomBrowserContext* browser_context); + // mate::Wrappable implementations: + virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate); + private: // Possible errors. enum ProtocolError { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 51f7c1bb811c..e5c5198f0341 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,7 +9,6 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" -#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/save_page_handler.h" @@ -444,14 +443,6 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { return v8::Local::New(isolate, cookies_); } -v8::Local Session::Protocol(v8::Isolate* isolate) { - if (protocol_.IsEmpty()) { - auto handle = atom::api::Protocol::Create(isolate, browser_context()); - protocol_.Reset(isolate, handle.ToV8()); - } - return v8::Local::New(isolate, protocol_); -} - v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { auto handle = atom::api::WebRequest::Create(isolate, browser_context()); @@ -499,7 +490,6 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::SetPermissionRequestHandler) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) - .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 63c4cfc612bd..02d8ba5cdec0 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -80,12 +80,10 @@ class Session: public mate::TrackableObject, mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); - v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); // Cached object. v8::Global cookies_; - v8::Global protocol_; v8::Global web_request_; scoped_refptr browser_context_; diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index caef0ad646b4..41cb48db09b9 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -4,10 +4,7 @@ if (!app.isReady()) { throw new Error('Can not initialize protocol module before app is ready'); } -const session = require('electron').session; - -// Returns the protocol property for default session. -const protocol = session.defaultSession.protocol; +const protocol = process.atomBinding('protocol').protocol; // Warn about removed APIs. var logAndThrow = function(callback, message) { @@ -19,10 +16,6 @@ var logAndThrow = function(callback, message) { } }; -protocol.fromPartition = function(partition) { - return session.fromPartition(partition).protocol; -}; - protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 4af3ba5b64be..69e7906ffbbb 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -41,6 +41,7 @@ REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_power_monitor); REFERENCE_MODULE(atom_browser_power_save_blocker); +REFERENCE_MODULE(atom_browser_protocol); REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_tray); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 483155b70652..215868bfdc8a 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -3,7 +3,6 @@ const http = require('http'); const path = require('path'); const qs = require('querystring'); const remote = require('electron').remote; -const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; describe('protocol module', function() { @@ -815,54 +814,4 @@ describe('protocol module', function() { }); }); }); - - describe('protocol.fromPartition', function() { - var partitionName = 'temp'; - var tempProtocol = protocol.fromPartition(partitionName); - var w = null; - - beforeEach(function() { - if (w != null) { - w.destroy(); - } - w = new BrowserWindow({ - show: false, - width: 400, - height: 400, - webPreferences: { - partition: partitionName - } - }); - }); - - afterEach(function() { - if (w != null) { - w.destroy(); - } - w = null; - }); - - it('handles requests from a partition', function(done) { - var handler = function(error, callback) { - callback({ - data: text - }); - }; - tempProtocol.registerStringProtocol(protocolName, handler, function(error) { - if (error) { - return done(error); - } - protocol.isProtocolHandled(protocolName, function(result) { - assert.equal(result, false); - }); - tempProtocol.isProtocolHandled(protocolName, function(result) { - assert.equal(result, true); - }); - }); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); - }); - }); }); From 6fcc197db8e98acd1d17c406504e30a5a5f5335b Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 14:22:19 +0530 Subject: [PATCH 130/132] webview: api to get webcontents and associated host webcontents --- atom/browser/api/atom_api_web_contents.cc | 16 ++++++++++++---- atom/browser/api/atom_api_web_contents.h | 4 ++++ .../native_mate_converters/content_converter.cc | 2 ++ atom/renderer/lib/web-view/web-view.js | 8 +++++++- docs/api/web-contents.md | 4 ++++ docs/api/web-view-tag.md | 4 ++++ spec/webview-spec.js | 13 +++++++++++++ 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ee6ad94ba77a..4935adbc75ad 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -218,7 +218,8 @@ WebContents::WebContents(content::WebContents* web_contents) WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) - : request_id_(0) { + : embedder_(nullptr), + request_id_(0) { // Whether it is a guest WebContents. bool is_guest = false; options.Get("isGuest", &is_guest); @@ -273,10 +274,10 @@ WebContents::WebContents(v8::Isolate* isolate, guest_delegate_->Initialize(this); NativeWindow* owner_window = nullptr; - WebContents* embedder = nullptr; - if (options.Get("embedder", &embedder) && embedder) { + if (options.Get("embedder", &embedder_) && embedder_) { // New WebContents's owner_window is the embedder's owner_window. - auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents()); + auto relay = + NativeWindowRelay::FromWebContents(embedder_->web_contents()); if (relay) owner_window = relay->window.get(); } @@ -1116,6 +1117,12 @@ v8::Local WebContents::Session(v8::Isolate* isolate) { return v8::Local::New(isolate, session_); } +content::WebContents* WebContents::HostWebContents() { + if (!embedder_) + return nullptr; + return embedder_->web_contents(); +} + v8::Local WebContents::DevToolsWebContents(v8::Isolate* isolate) { if (devtools_web_contents_.IsEmpty()) return v8::Null(isolate); @@ -1199,6 +1206,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetProperty("session", &WebContents::Session) + .SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("debugger", &WebContents::Debugger); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 63c4a0177716..b4f29090dbd3 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -147,6 +147,7 @@ class WebContents : public mate::TrackableObject, // Properties. v8::Local Session(v8::Isolate* isolate); + content::WebContents* HostWebContents(); v8::Local DevToolsWebContents(v8::Isolate* isolate); v8::Local Debugger(v8::Isolate* isolate); @@ -287,6 +288,9 @@ class WebContents : public mate::TrackableObject, scoped_ptr guest_delegate_; + // The host webcontents that may contain this webcontents. + WebContents* embedder_; + // The type of current WebContents. Type type_; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 699f101d0e4b..f5d81d085bc1 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -173,6 +173,8 @@ bool Converter::FromV8( // static v8::Local Converter::ToV8( v8::Isolate* isolate, content::WebContents* val) { + if (!val) + return v8::Null(isolate); return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); } diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 7e38bb33715a..44fc10421621 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -388,7 +388,7 @@ var registerWebViewElement = function() { 'downloadURL', 'inspectServiceWorker', 'print', - 'printToPDF' + 'printToPDF', ]; nonblockMethods = [ 'executeJavaScript', @@ -430,6 +430,12 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } + // WebContents associated with this webview. + proto.getWebContents = function() { + var internal = v8Util.getHiddenValue(this, 'internal'); + return internal.webContents; + }; + // Deprecated. deprecate.rename(proto, 'getUrl', 'getURL'); window.WebView = webFrame.registerEmbedderCustomElement('webview', { diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index e0139a29fa6c..dde701d7f488 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -842,6 +842,10 @@ win.webContents.on('did-finish-load', function() { Returns the [session](session.md) object used by this webContents. +### `webContents.hostWebContents` + +Returns the `WebContents` that might own this `WebContents`. + ### `webContents.devToolsWebContents` Get the `WebContents` of DevTools for this `WebContents`. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index b4f139d475ca..4a0697ad843d 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -438,6 +438,10 @@ Sends an input `event` to the page. See [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) for detailed description of `event` object. +### `.getWebContents()` + +Returns the [WebContents](web-contents.md) associated with this `webview`. + ## DOM events The following DOM events are available to the `webview` tag: diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 54b544def0db..d73a177d0970 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -703,4 +703,17 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + + describe('.getWebContents', function() { + it('can return the webcontents associated', function(done) { + webview.addEventListener('did-finish-load', function() { + const webviewContents = webview.getWebContents(); + assert(webviewContents); + assert.equal(webviewContents.getURL(), 'about:blank'); + done(); + }); + webview.src = "about:blank"; + document.body.appendChild(webview); + }); + }); }); From d2b48b2aa7ff7ed3bb257f96ef0ed6d46c4c28b9 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Wed, 24 Feb 2016 14:01:26 +0100 Subject: [PATCH 131/132] Fix crash in mate::Converter::ToV8 The net::URLRequest::url() method calls vector::back(), which is undefined when the url_chain is empty --- atom/common/native_mate_converters/net_converter.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 94081b88a3d9..184f1c3fecff 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -27,7 +27,9 @@ v8::Local Converter::ToV8( v8::Isolate* isolate, const net::URLRequest* val) { scoped_ptr dict(new base::DictionaryValue); dict->SetString("method", val->method()); - dict->SetStringWithoutPathExpansion("url", val->url().spec()); + std::string url; + if (!val->url_chain().empty()) url = val->url().spec(); + dict->SetStringWithoutPathExpansion("url", url); dict->SetString("referrer", val->referrer()); scoped_ptr list(new base::ListValue); atom::GetUploadData(list.get(), val); From fee56df40074b6730e71591db964477c8fce8b91 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Wed, 24 Feb 2016 11:15:21 -0800 Subject: [PATCH 132/132] Rename function `FilterAccecelator` to `FilterAccelerator` in `submenu_button.cc`. --- atom/browser/ui/views/submenu_button.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index bedbb98832df..7f413d519c2b 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -15,7 +15,7 @@ namespace atom { namespace { // Filter out the "&" in menu label. -base::string16 FilterAccecelator(const base::string16& label) { +base::string16 FilterAccelerator(const base::string16& label) { base::string16 out; base::RemoveChars(label, base::ASCIIToUTF16("&").c_str(), &out); return out; @@ -26,7 +26,7 @@ base::string16 FilterAccecelator(const base::string16& label) { SubmenuButton::SubmenuButton(views::ButtonListener* listener, const base::string16& title, views::MenuButtonListener* menu_button_listener) - : views::MenuButton(listener, FilterAccecelator(title), + : views::MenuButton(listener, FilterAccelerator(title), menu_button_listener, false), accelerator_(0), show_underline_(false),