Merge branch 'master' into msb/aspect-ratio

This commit is contained in:
Michael S. Barthelemy 2015-07-16 13:57:38 -04:00
commit 423ea00263
16 changed files with 120 additions and 43 deletions

View file

@ -4,7 +4,7 @@
'product_name%': 'Electron', 'product_name%': 'Electron',
'company_name%': 'GitHub, Inc', 'company_name%': 'GitHub, Inc',
'company_abbr%': 'github', 'company_abbr%': 'github',
'version%': '0.29.2', 'version%': '0.30.0',
}, },
'includes': [ 'includes': [
'filenames.gypi', 'filenames.gypi',

View file

@ -237,7 +237,7 @@ app.once('ready', function() {
}, },
{ {
label: 'Toggle &Developer Tools', label: 'Toggle &Developer Tools',
accelerator: 'Alt+Ctrl+I', accelerator: 'Shift+Ctrl+I',
click: function() { click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow(); var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow) if (focusedWindow)

View file

@ -17,7 +17,7 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>atom.icns</string> <string>atom.icns</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.29.2</string> <string>0.30.0</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.8.0</string> <string>10.8.0</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>

View file

@ -56,8 +56,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,29,2,0 FILEVERSION 0,30,0,0
PRODUCTVERSION 0,29,2,0 PRODUCTVERSION 0,30,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -74,12 +74,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "GitHub, Inc." VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron" VALUE "FileDescription", "Electron"
VALUE "FileVersion", "0.29.2" VALUE "FileVersion", "0.30.0"
VALUE "InternalName", "electron.exe" VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe" VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron" VALUE "ProductName", "Electron"
VALUE "ProductVersion", "0.29.2" VALUE "ProductVersion", "0.30.0"
VALUE "SquirrelAwareVersion", "1" VALUE "SquirrelAwareVersion", "1"
END END
END END

View file

@ -4,17 +4,66 @@
#include "atom/browser/web_dialog_helper.h" #include "atom/browser/web_dialog_helper.h"
#include <string>
#include <vector> #include <vector>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h" #include "atom/browser/ui/file_dialog.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_enumerator.h" #include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_file_info.h" #include "content/public/common/file_chooser_file_info.h"
#include "net/base/mime_util.h"
#include "ui/shell_dialogs/selected_file_info.h" #include "ui/shell_dialogs/selected_file_info.h"
namespace {
const char kSelectFileLastDirectory[] = "selectfile.last_directory";
file_dialog::Filters GetFileTypesFromAcceptType(
const std::vector<base::string16>& accept_types) {
file_dialog::Filters filters;
if (accept_types.empty())
return filters;
std::vector<base::FilePath::StringType> extensions;
for (const auto& accept_type : accept_types) {
std::string ascii_type = base::UTF16ToASCII(accept_type);
if (ascii_type[0] == '.') {
// If the type starts with a period it is assumed to be a file extension,
// like `.txt`, // so we just have to add it to the list.
base::FilePath::StringType extension(
ascii_type.begin(), ascii_type.end());
// Skip the first character.
extensions.push_back(extension.substr(1));
} else {
if (ascii_type == "image/*" || ascii_type == "audio/*" ||
ascii_type == "video/*") {
// For MIME Type
net::GetExtensionsForMimeType(ascii_type, &extensions);
}
}
}
filters.push_back(file_dialog::Filter());
for (const auto& extension : extensions) {
#if defined(OS_WIN)
filters[0].second.push_back(base::UTF16ToASCII(extension));
#else
filters[0].second.push_back(extension);
#endif
}
return filters;
}
} // namespace
namespace atom { namespace atom {
WebDialogHelper::WebDialogHelper(NativeWindow* window) WebDialogHelper::WebDialogHelper(NativeWindow* window)
@ -25,15 +74,18 @@ WebDialogHelper::WebDialogHelper(NativeWindow* window)
WebDialogHelper::~WebDialogHelper() { WebDialogHelper::~WebDialogHelper() {
} }
void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) { const content::FileChooserParams& params) {
std::vector<content::FileChooserFileInfo> result; std::vector<content::FileChooserFileInfo> result;
file_dialog::Filters filters = GetFileTypesFromAcceptType(
params.accept_types);
if (params.mode == content::FileChooserParams::Save) { if (params.mode == content::FileChooserParams::Save) {
base::FilePath path; base::FilePath path;
if (file_dialog::ShowSaveDialog(window_, if (file_dialog::ShowSaveDialog(window_,
base::UTF16ToUTF8(params.title), base::UTF16ToUTF8(params.title),
params.default_file_name, params.default_file_name,
file_dialog::Filters(), filters,
&path)) { &path)) {
content::FileChooserFileInfo info; content::FileChooserFileInfo info;
info.file_path = path; info.file_path = path;
@ -56,10 +108,14 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
} }
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
window_->web_contents()->GetBrowserContext());
base::FilePath default_file_path = browser_context->prefs()->GetFilePath(
kSelectFileLastDirectory).Append(params.default_file_name);
if (file_dialog::ShowOpenDialog(window_, if (file_dialog::ShowOpenDialog(window_,
base::UTF16ToUTF8(params.title), base::UTF16ToUTF8(params.title),
params.default_file_name, default_file_path,
file_dialog::Filters(), filters,
flags, flags,
&paths)) { &paths)) {
for (auto& path : paths) { for (auto& path : paths) {
@ -68,6 +124,10 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
info.display_name = path.BaseName().value(); info.display_name = path.BaseName().value();
result.push_back(info); result.push_back(info);
} }
if (!paths.empty()) {
browser_context->prefs()->SetFilePath(kSelectFileLastDirectory,
paths[0].DirName());
}
} }
} }

View file

@ -54,6 +54,11 @@ bool GetChildNode(const base::DictionaryValue* root,
const std::string& name, const std::string& name,
const base::DictionaryValue* dir, const base::DictionaryValue* dir,
const base::DictionaryValue** out) { const base::DictionaryValue** out) {
if (name == "") {
*out = root;
return true;
}
const base::DictionaryValue* files = NULL; const base::DictionaryValue* files = NULL;
return GetFilesNode(root, dir, &files) && return GetFilesNode(root, dir, &files) &&
files->GetDictionaryWithoutPathExpansion(name, out); files->GetDictionaryWithoutPathExpansion(name, out);

View file

@ -6,8 +6,8 @@
#define ATOM_VERSION_H #define ATOM_VERSION_H
#define ATOM_MAJOR_VERSION 0 #define ATOM_MAJOR_VERSION 0
#define ATOM_MINOR_VERSION 29 #define ATOM_MINOR_VERSION 30
#define ATOM_PATCH_VERSION 2 #define ATOM_PATCH_VERSION 0
#define ATOM_VERSION_IS_RELEASE 1 #define ATOM_VERSION_IS_RELEASE 1

View file

@ -66,6 +66,3 @@
* [빌드 설명서 (Windows)](development/build-instructions-windows-ko.md) * [빌드 설명서 (Windows)](development/build-instructions-windows-ko.md)
* [빌드 설명서 (Linux)](development/build-instructions-linux-ko.md) * [빌드 설명서 (Linux)](development/build-instructions-linux-ko.md)
* [디버거에서 디버그 심볼 서버 설정](development/setting-up-symbol-server-ko.md) * [디버거에서 디버그 심볼 서버 설정](development/setting-up-symbol-server-ko.md)
이 문서는 [@preco21](https://github.com/preco21) 에 의해 번역되었습니다.
문서내에서 오타나 잘못된 번역이 발견될 경우 해당 repo를 fork한 후 수정하여 PR을 올리거나 `plusb21@gmail.com` 이메일로 알려주시면 감사하겠습니다.

View file

@ -760,7 +760,7 @@ Calling `event.preventDefault()` can prevent creating new windows.
* `event` Event * `event` Event
* `url` String * `url` String
Emitted when user or the page wants to start an navigation, it can happen when Emitted when user or the page wants to start a navigation, it can happen when
`window.location` object is changed or user clicks a link in the page. `window.location` object is changed or user clicks a link in the page.
This event will not emit when the navigation is started programmatically with APIs This event will not emit when the navigation is started programmatically with APIs

View file

@ -1,9 +1,9 @@
# global-shortcut # global-shortcut
The `global-shortcut` module can register/unregister a global keyboard shortcut The `global-shortcut` module can register/unregister a global keyboard shortcut
in operating system, so that you can customize the operations for various shortcuts. with the operating system, so that you can customize the operations for various shortcuts.
Note that the shortcut is global, even if the app does not get focused, it will still work. Note that the shortcut is global; it will work even if the app does not have the keyboard focus.
You should not use this module until the ready event of app module gets emitted. You should not use this module until the `ready` event of the app module is emitted.
```javascript ```javascript
var app = require('app'); var app = require('app');
@ -37,14 +37,14 @@ app.on('will-quit', function() {
* `accelerator` [Accelerator](accelerator.md) * `accelerator` [Accelerator](accelerator.md)
* `callback` Function * `callback` Function
Registers a global shortcut of `accelerator`, the `callback` would be called when Registers a global shortcut of `accelerator`. The `callback` is called when
the registered shortcut is pressed by user. the registered shortcut is pressed by the user.
## globalShortcut.isRegistered(accelerator) ## globalShortcut.isRegistered(accelerator)
* `accelerator` [Accelerator](accelerator.md) * `accelerator` [Accelerator](accelerator.md)
Returns `true` or `false` depending on if the shortcut `accelerator` is registered. Returns `true` or `false` depending on whether the shortcut `accelerator` is registered.
## globalShortcut.unregister(accelerator) ## globalShortcut.unregister(accelerator)

View file

@ -37,6 +37,11 @@ Registers a custom protocol of `scheme`, the `handler` would be called with
You need to return a request job in the `handler` to specify which type of You need to return a request job in the `handler` to specify which type of
response you would like to send. response you would like to send.
By default the scheme is treated like `http:`, which is parsed differently
from protocols that follows "generic URI syntax" like `file:`, so you probably
want to call `protocol.registerStandardSchemes` to make your scheme treated as
standard scheme.
## protocol.unregisterProtocol(scheme, callback) ## protocol.unregisterProtocol(scheme, callback)
* `scheme` String * `scheme` String
@ -48,7 +53,11 @@ Unregisters the custom protocol of `scheme`.
* `value` Array * `value` Array
`value` is an array of custom schemes to be registered to the standard. `value` is an array of custom schemes to be registered as standard schemes.
A standard scheme adheres to what RFC 3986 calls
[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). This
includes `file:` and `filesystem:`.
## protocol.isHandledProtocol(scheme, callback) ## protocol.isHandledProtocol(scheme, callback)

View file

@ -2,7 +2,7 @@
When `window.open` is called to create a new window in web page, a new instance When `window.open` is called to create a new window in web page, a new instance
of `BrowserWindow` will be created for the `url`, and a proxy will be returned of `BrowserWindow` will be created for the `url`, and a proxy will be returned
to `window.open` to let the page to have limited control over it. to `window.open` to let the page have limited control over it.
The proxy only has some limited standard functionality implemented to be The proxy only has some limited standard functionality implemented to be
compatible with traditional web pages, for full control of the created window compatible with traditional web pages, for full control of the created window

View file

@ -4,39 +4,40 @@
Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers. Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers.
It doesn't mean Electron is a JavaScript binding to GUI libraries. Instead, This doesn't mean Electron is a JavaScript binding to GUI libraries. Instead,
Electron uses web pages as its GUI, so you could also see it as a minimal Electron uses web pages as its GUI, so you could also see it as a minimal
Chromium browser, controlled by JavaScript. Chromium browser, controlled by JavaScript.
### Main process ### Main process
In Electron, the process that runs `package.json`'s `main` script is called In Electron, the process that runs `package.json`'s `main` script is called
__the main process__. The script that runs in the main process, can display GUI by __the main process__. The script that runs in the main process can display a GUI by
creating web pages. creating web pages.
### Renderer process ### Renderer process
Since Electron uses Chromium for displaying web pages, Chromium's Since Electron uses Chromium for displaying web pages, Chromium's
multi-processes architecture is also used. Each web page in Electron runs in multi-process architecture is also used. Each web page in Electron runs in
its own process, which is called __the renderer process__. its own process, which is called __the renderer process__.
In normal browsers web pages usually run in a sandboxed environment and are not In normal browsers, web pages usually run in a sandboxed environment and are not
allowed access to native resources. Electron users however, have the power to use allowed access to native resources. Electron users, however, have the power to use
io.js APIs in web pages allowing lower level operating system interactions. io.js APIs in web pages allowing lower level operating system interactions.
### Differences between main process and renderer process ### Differences between main process and renderer process
The main process creates web pages by creating `BrowserWindow` instances. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process The main process creates web pages by creating `BrowserWindow` instances. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process
would also be terminated. is also terminated.
The main process manages all web pages and their corresponding renderer The main process manages all web pages and their corresponding renderer
processes, each renderer process is isolated and only cares processes. Each renderer process is isolated and only cares
about the web page running in it. about the web page running in it.
In web pages, it is not allowed to call native GUI related APIs because managing In web pages, it is not allowed to call native GUI related APIs because managing
native GUI resources in web pages is very dangerous and easy to leak resources. native GUI resources in web pages is very dangerous and it is easy to leak resources.
If you want to do GUI operations in web pages, you have to communicate with If you want to perform GUI operations in a web page, the renderer process of the web
the main process to do it there. page must communicate with the main process to request the main process perform those
operations.
In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for
communication between main process and renderer process. And there is also a communication between main process and renderer process. And there is also a
@ -77,20 +78,20 @@ var BrowserWindow = require('browser-window'); // Module to create native brows
require('crash-reporter').start(); require('crash-reporter').start();
// Keep a global reference of the window object, if you don't, the window will // Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed. // be closed automatically when the JavaScript object is GCed.
var mainWindow = null; var mainWindow = null;
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function() { app.on('window-all-closed', function() {
// On OSX it is common for applications and their menu bar // On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform != 'darwin') { if (process.platform != 'darwin') {
app.quit(); app.quit();
} }
}); });
// This method will be called when Electron has done everything // This method will be called when Electron has finished
// initialization and ready for creating browser windows. // initialization and is ready to create browser windows.
app.on('ready', function() { app.on('ready', function() {
// Create the browser window. // Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600}); mainWindow = new BrowserWindow({width: 800, height: 600});

View file

@ -90,10 +90,6 @@ def main():
upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME))
if PLATFORM == 'win32' and not tag_exists: if PLATFORM == 'win32' and not tag_exists:
# Upload PDBs to Windows symbol server.
execute([sys.executable,
os.path.join(SOURCE_ROOT, 'script', 'upload-windows-pdb.py')])
# Upload node headers. # Upload node headers.
execute([sys.executable, execute([sys.executable,
os.path.join(SOURCE_ROOT, 'script', 'upload-node-headers.py'), os.path.join(SOURCE_ROOT, 'script', 'upload-node-headers.py'),

View file

@ -85,6 +85,11 @@ describe 'asar package', ->
done() done()
describe 'fs.lstatSync', -> describe 'fs.lstatSync', ->
it 'handles path with trailing slash correctly', ->
p = path.join fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'
fs.lstatSync p
fs.lstatSync p + '/'
it 'returns information of root', -> it 'returns information of root', ->
p = path.join fixtures, 'asar', 'a.asar' p = path.join fixtures, 'asar', 'a.asar'
stats = fs.lstatSync p stats = fs.lstatSync p
@ -136,6 +141,10 @@ describe 'asar package', ->
assert.throws throws, /ENOENT/ assert.throws throws, /ENOENT/
describe 'fs.lstat', -> describe 'fs.lstat', ->
it 'handles path with trailing slash correctly', (done) ->
p = path.join fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'
fs.lstat p + '/', done
it 'returns information of root', (done) -> it 'returns information of root', (done) ->
p = path.join fixtures, 'asar', 'a.asar' p = path.join fixtures, 'asar', 'a.asar'
stats = fs.lstat p, (err, stats) -> stats = fs.lstat p, (err, stats) ->

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit 6328c6104131e623da87f479ea305b83169099b8 Subproject commit c5f41a6edf6109e862c4c286d0c156e0099678e0