diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 98d46f895a..c7a2a542d1 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -16,6 +16,7 @@ #include "base/environment.h" #include "base/files/file_path.h" #include "base/path_service.h" +#include "brightray/browser/brightray_paths.h" #include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" @@ -26,10 +27,6 @@ #include "atom/common/node_includes.h" -#if defined(OS_LINUX) -#include "base/nix/xdg_util.h" -#endif - using atom::Browser; namespace mate { @@ -64,6 +61,30 @@ namespace api { namespace { +// Return the path constant from string. +int GetPathConstant(const std::string& name) { + if (name == "appData") + return brightray::DIR_APP_DATA; + else if (name == "userData") + return brightray::DIR_USER_DATA; + else if (name == "cache") + return brightray::DIR_CACHE; + else if (name == "userCache") + return brightray::DIR_USER_CACHE; + else if (name == "home") + return base::DIR_HOME; + else if (name == "temp") + return base::DIR_TEMP; + else if (name == "userDesktop") + return base::DIR_USER_DESKTOP; + else if (name == "exe") + return base::FILE_EXE; + else if (name == "module") + return base::FILE_MODULE; + else + return -1; +} + class ResolveProxyHelper { public: ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback) @@ -142,19 +163,26 @@ void App::OnFinishLaunching() { Emit("ready"); } -base::FilePath App::GetDataPath() { +base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { + bool succeed = false; base::FilePath path; -#if defined(OS_LINUX) - scoped_ptr env(base::Environment::Create()); - path = base::nix::GetXDGDirectory(env.get(), - base::nix::kXdgConfigHomeEnvVar, - base::nix::kDotConfigDir); -#else - PathService::Get(base::DIR_APP_DATA, &path); -#endif + int key = GetPathConstant(name); + if (key >= 0) + succeed = PathService::Get(key, &path); + if (!succeed) + args->ThrowError("Failed to get path"); + return path; +} - return path.Append(base::FilePath::FromUTF8Unsafe( - Browser::Get()->GetName())); +void App::SetPath(mate::Arguments* args, + const std::string& name, + const base::FilePath& path) { + bool succeed = false; + int key = GetPathConstant(name); + if (key >= 0) + succeed = PathService::Override(key, path); + if (!succeed) + args->ThrowError("Failed to set path"); } void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { @@ -187,7 +215,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) #endif - .SetMethod("getDataPath", &App::GetDataPath) + .SetMethod("setPath", &App::SetPath) + .SetMethod("getPath", &App::GetPath) .SetMethod("resolveProxy", &App::ResolveProxy) .SetMethod("setDesktopName", &App::SetDesktopName); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index a9e2a17a13..41a820b7a7 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -18,6 +18,10 @@ namespace base { class FilePath; } +namespace mate { +class Arguments; +} + namespace atom { namespace api { @@ -48,7 +52,12 @@ class App : public mate::EventEmitter, v8::Isolate* isolate) override; private: - base::FilePath GetDataPath(); + // Get/Set the pre-defined path in PathService. + base::FilePath GetPath(mate::Arguments* args, const std::string& name); + void SetPath(mate::Arguments* args, + const std::string& name, + const base::FilePath& path); + void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void SetDesktopName(const std::string& desktop_name); diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 51fd66098a..aad56fd912 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -5,9 +5,6 @@ bindings = process.atomBinding 'app' app = bindings.app app.__proto__ = EventEmitter.prototype -app.getHomeDir = -> - process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME'] - app.setApplicationMenu = (menu) -> require('menu').setApplicationMenu menu @@ -32,6 +29,9 @@ if process.platform is 'darwin' app.once 'ready', -> app.emit 'finish-launching' app.terminate = app.quit app.exit = process.exit +app.getHomeDir = -> app.getPath 'home' +app.getDataPath = -> app.getPath 'userData' +app.setDataPath = (path) -> app.setPath 'userData', path # Only one App object pemitted. module.exports = app diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 8f6e387403..103c05cc11 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -41,6 +41,8 @@ if (option.file && !option.webdriver) { app.setName(packageJson.productName); else if (packageJson.name) app.setName(packageJson.name); + app.setPath('userData', path.join(app.getPath('appData'), app.getName())); + app.setPath('userCache', path.join(app.getPath('cache'), app.getName())); } // Run the app. diff --git a/atom/browser/lib/chrome-extension.coffee b/atom/browser/lib/chrome-extension.coffee index e62ad5250d..1b987187c4 100644 --- a/atom/browser/lib/chrome-extension.coffee +++ b/atom/browser/lib/chrome-extension.coffee @@ -34,15 +34,9 @@ getExtensionInfoFromPath = (srcDirectory) -> srcDirectory: srcDirectory extensionInfoMap[manifest.name] -# Load persistented extensions. -loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions' - -try - loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath) - loadedExtensions = [] unless Array.isArray loadedExtensions - # Preheat the extensionInfo cache. - getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions -catch e +# The loaded extensions cache and its persistent path. +loadedExtensions = null +loadedExtensionsPath = null # Persistent loaded extensions. app.on 'will-quit', -> @@ -59,6 +53,16 @@ app.once 'ready', -> protocol = require 'protocol' BrowserWindow = require 'browser-window' + # Load persistented extensions. + loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions' + + try + loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath) + loadedExtensions = [] unless Array.isArray loadedExtensions + # Preheat the extensionInfo cache. + getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions + catch e + # The chrome-extension: can map a extension URL request to real file path. protocol.registerProtocol 'chrome-extension', (request) -> parsed = url.parse request.url diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index ae2419b219..d3234db757 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -90,6 +90,10 @@ process.once 'BIND_DONE', -> else app.setDesktopName '#{app.getName()}.desktop' + # Set the user path according to application's name. + app.setPath 'userData', path.join(app.getPath('appData'), app.getName()) + app.setPath 'userCache', path.join(app.getPath('cache'), app.getName()) + # Load the chrome extension support. require './chrome-extension.js' diff --git a/docs/api/app.md b/docs/api/app.md index b7cb5f35aa..4ac3776926 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -91,13 +91,47 @@ executed. It is possible that a window cancels the quitting by returning Quit the application directly, it will not try to close all windows so cleanup code will not run. -## app.getDataPath() +## app.getPath(name) -Returns the path for storing configuration files, with app name appended. +* `name` String - * `%APPDATA%\MyAppName` on Windows - * `~/.config/MyAppName` on Linux - * `~/Library/Application Support/MyAppName` on OS X +Retrieves a path to a special directory or file associated with `name`. On +failure an `Error` would throw. + +You can request following paths by the names: + +* `home`: User's home directory +* `appData`: Per-user application data directory, by default it is pointed to: + * `%APPDATA%` on Windows + * `$XDG_CONFIG_HOME` or `~/.config` on Linux + * `~/Library/Application Support` on OS X +* `userData`: The directory for storing your app's configuration files, by + default it is the `appData` directory appended with your app's name +* `cache`: Per-user application cache directory, by default it is pointed to: + * `%APPDATA%` on Window, which doesn't has a universal place for cache + * `$XDG_CACHE_HOME` or `~/.cache` on Linux + * `~/Library/Caches` on OS X +* `userCache`: The directory for placing your app's caches, by default it is the + `cache` directory appended with your app's name +* `temp`: Temporary directory +* `userDesktop`: The current user's Desktop directory +* `exe`: The current executable file +* `module`: The `libchromiumcontent` library + +## app.setPath(name, path) + +* `name` String +* `path` String + +Overrides the `path` to a special directory or file associated with `name`. if +the path specifies a directory that does not exist, the directory will be +created by this method. On failure an `Error` would throw. + +You can only override paths of `name`s defined in `app.getPath`. + +By default web pages' cookies and caches will be stored under `userData` +directory, if you want to change this location, you have to override the +`userData` path before the `ready` event of `app` module gets emitted. ## app.getVersion() diff --git a/vendor/brightray b/vendor/brightray index 09dc5f11e9..ad17292154 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 09dc5f11e9c83e6ff3c2b6b1b58ceb2b8eae35c4 +Subproject commit ad17292154ddd2436c377bbe2d10fa213338f4fa