diff --git a/atom.gyp b/atom.gyp index 83ea66adbabd..d8da82cd548f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.29.2', + 'version%': '0.30.0', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 838cb4c2bb2e..fd3a6b596b6b 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -237,7 +237,7 @@ app.once('ready', function() { }, { label: 'Toggle &Developer Tools', - accelerator: 'Alt+Ctrl+I', + accelerator: 'Shift+Ctrl+I', click: function() { var focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index edbeda36e8a5..68ce951ed4d4 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.29.2 + 0.30.0 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 7f6d618d48dc..80714c55fd25 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,29,2,0 - PRODUCTVERSION 0,29,2,0 + FILEVERSION 0,30,0,0 + PRODUCTVERSION 0,30,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.29.2" + VALUE "FileVersion", "0.30.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.29.2" + VALUE "ProductVersion", "0.30.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index f6f233453582..93cb32cba7c7 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -4,17 +4,66 @@ #include "atom/browser/web_dialog_helper.h" +#include #include +#include "atom/browser/atom_browser_context.h" +#include "atom/browser/native_window.h" #include "atom/browser/ui/file_dialog.h" #include "base/bind.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 "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/file_chooser_file_info.h" +#include "net/base/mime_util.h" #include "ui/shell_dialogs/selected_file_info.h" +namespace { + +const char kSelectFileLastDirectory[] = "selectfile.last_directory"; + +file_dialog::Filters GetFileTypesFromAcceptType( + const std::vector& accept_types) { + file_dialog::Filters filters; + if (accept_types.empty()) + return filters; + + std::vector 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 { WebDialogHelper::WebDialogHelper(NativeWindow* window) @@ -25,15 +74,18 @@ WebDialogHelper::WebDialogHelper(NativeWindow* window) WebDialogHelper::~WebDialogHelper() { } + void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, const content::FileChooserParams& params) { std::vector result; + file_dialog::Filters filters = GetFileTypesFromAcceptType( + params.accept_types); if (params.mode == content::FileChooserParams::Save) { base::FilePath path; if (file_dialog::ShowSaveDialog(window_, base::UTF16ToUTF8(params.title), params.default_file_name, - file_dialog::Filters(), + filters, &path)) { content::FileChooserFileInfo info; info.file_path = path; @@ -56,10 +108,14 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, } std::vector paths; + AtomBrowserContext* browser_context = static_cast( + window_->web_contents()->GetBrowserContext()); + base::FilePath default_file_path = browser_context->prefs()->GetFilePath( + kSelectFileLastDirectory).Append(params.default_file_name); if (file_dialog::ShowOpenDialog(window_, base::UTF16ToUTF8(params.title), - params.default_file_name, - file_dialog::Filters(), + default_file_path, + filters, flags, &paths)) { for (auto& path : paths) { @@ -68,6 +124,10 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, info.display_name = path.BaseName().value(); result.push_back(info); } + if (!paths.empty()) { + browser_context->prefs()->SetFilePath(kSelectFileLastDirectory, + paths[0].DirName()); + } } } diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 79b82416cd0a..be99530c9c98 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -54,6 +54,11 @@ bool GetChildNode(const base::DictionaryValue* root, const std::string& name, const base::DictionaryValue* dir, const base::DictionaryValue** out) { + if (name == "") { + *out = root; + return true; + } + const base::DictionaryValue* files = NULL; return GetFilesNode(root, dir, &files) && files->GetDictionaryWithoutPathExpansion(name, out); diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index f8543df72785..64d0c7bfd73d 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 29 -#define ATOM_PATCH_VERSION 2 +#define ATOM_MINOR_VERSION 30 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/docs/README-ko.md b/docs/README-ko.md index 50c4b2c9c9ca..b48c6a42c516 100644 --- a/docs/README-ko.md +++ b/docs/README-ko.md @@ -66,6 +66,3 @@ * [빌드 설명서 (Windows)](development/build-instructions-windows-ko.md) * [빌드 설명서 (Linux)](development/build-instructions-linux-ko.md) * [디버거에서 디버그 심볼 서버 설정](development/setting-up-symbol-server-ko.md) - -이 문서는 [@preco21](https://github.com/preco21) 에 의해 번역되었습니다. -문서내에서 오타나 잘못된 번역이 발견될 경우 해당 repo를 fork한 후 수정하여 PR을 올리거나 `plusb21@gmail.com` 이메일로 알려주시면 감사하겠습니다. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 61f985ed9518..48a118ffa3c2 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -760,7 +760,7 @@ Calling `event.preventDefault()` can prevent creating new windows. * `event` Event * `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. This event will not emit when the navigation is started programmatically with APIs diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index 16399cfbfe49..54da5638d194 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -1,9 +1,9 @@ # global-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. -Note that the shortcut is global, even if the app does not get focused, it will still work. -You should not use this module until the ready event of app module gets emitted. +with the operating system, so that you can customize the operations for various shortcuts. +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 the app module is emitted. ```javascript var app = require('app'); @@ -37,14 +37,14 @@ app.on('will-quit', function() { * `accelerator` [Accelerator](accelerator.md) * `callback` Function -Registers a global shortcut of `accelerator`, the `callback` would be called when -the registered shortcut is pressed by user. +Registers a global shortcut of `accelerator`. The `callback` is called when +the registered shortcut is pressed by the user. ## globalShortcut.isRegistered(accelerator) * `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) diff --git a/docs/api/protocol.md b/docs/api/protocol.md index a076e3640daa..2734546516e3 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -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 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) * `scheme` String @@ -48,7 +53,11 @@ Unregisters the custom protocol of `scheme`. * `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) diff --git a/docs/api/window-open.md b/docs/api/window-open.md index 23bcf2b95f33..fa10b2e7d055 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -2,7 +2,7 @@ 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 -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 compatible with traditional web pages, for full control of the created window diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 8f723bbcf64e..ae60fb27ec71 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -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. -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 Chromium browser, controlled by JavaScript. ### Main process 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. ### Renderer process 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__. -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 +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 io.js APIs in web pages allowing lower level operating system interactions. ### 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 -would also be terminated. +is also terminated. 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. 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. -If you want to do GUI operations in web pages, you have to communicate with -the main process to do it there. +native GUI resources in web pages is very dangerous and it is easy to leak 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 the main process perform those +operations. 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 @@ -77,20 +78,20 @@ var BrowserWindow = require('browser-window'); // Module to create native brows require('crash-reporter').start(); // 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; // Quit when all windows are closed. 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 if (process.platform != 'darwin') { app.quit(); } }); -// This method will be called when Electron has done everything -// initialization and ready for creating browser windows. +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. app.on('ready', function() { // Create the browser window. mainWindow = new BrowserWindow({width: 800, height: 600}); diff --git a/script/upload.py b/script/upload.py index 9757fe60635e..6fc421e6b7a2 100755 --- a/script/upload.py +++ b/script/upload.py @@ -90,10 +90,6 @@ def main(): upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) 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. execute([sys.executable, os.path.join(SOURCE_ROOT, 'script', 'upload-node-headers.py'), diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index 977676a1936a..a49417258fec 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -85,6 +85,11 @@ describe 'asar package', -> done() 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', -> p = path.join fixtures, 'asar', 'a.asar' stats = fs.lstatSync p @@ -136,6 +141,10 @@ describe 'asar package', -> assert.throws throws, /ENOENT/ 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) -> p = path.join fixtures, 'asar', 'a.asar' stats = fs.lstat p, (err, stats) -> diff --git a/vendor/brightray b/vendor/brightray index 6328c6104131..c5f41a6edf61 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 6328c6104131e623da87f479ea305b83169099b8 +Subproject commit c5f41a6edf6109e862c4c286d0c156e0099678e0