Merge pull request #136 from atom/fix-ua

Use name and version information of package.json
This commit is contained in:
Cheng Zhao 2013-12-04 21:44:35 -08:00
commit 3c60e07653
13 changed files with 192 additions and 17 deletions

View file

@ -101,11 +101,38 @@ v8::Handle<v8::Value> App::Focus(const v8::Arguments &args) {
// static // static
v8::Handle<v8::Value> App::GetVersion(const v8::Arguments &args) { v8::Handle<v8::Value> App::GetVersion(const v8::Arguments &args) {
return ToV8Value(Browser::Get()->GetVersion());
}
// static
v8::Handle<v8::Value> App::SetVersion(const v8::Arguments &args) {
v8::HandleScope scope; v8::HandleScope scope;
std::string version(Browser::Get()->GetVersion()); std::string version;
if (!FromV8Arguments(args, &version))
return node::ThrowError("Bad argument");
return v8::String::New(version.data(), version.size()); Browser::Get()->SetVersion(version);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::GetName(const v8::Arguments &args) {
return ToV8Value(Browser::Get()->GetName());
}
// static
v8::Handle<v8::Value> App::SetName(const v8::Arguments &args) {
v8::HandleScope scope;
std::string name;
if (!FromV8Arguments(args, &name))
return node::ThrowError("Bad argument");
Browser::Get()->SetName(name);
return v8::Undefined();
} }
// static // static
@ -144,7 +171,10 @@ v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
// static // static
v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) { v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
std::string type = FromV8Value(args[0]); std::string type;
if (!FromV8Arguments(args, &type))
return node::ThrowError("Bad argument");
int request_id = -1; int request_id = -1;
if (type == "critical") if (type == "critical")
@ -154,7 +184,7 @@ v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
else else
return node::ThrowTypeError("Invalid bounce type"); return node::ThrowTypeError("Invalid bounce type");
return v8::Integer::New(request_id); return ToV8Value(request_id);
} }
// static // static
@ -190,6 +220,9 @@ void App::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "terminate", Terminate); NODE_SET_PROTOTYPE_METHOD(t, "terminate", Terminate);
NODE_SET_PROTOTYPE_METHOD(t, "focus", Focus); NODE_SET_PROTOTYPE_METHOD(t, "focus", Focus);
NODE_SET_PROTOTYPE_METHOD(t, "getVersion", GetVersion); NODE_SET_PROTOTYPE_METHOD(t, "getVersion", GetVersion);
NODE_SET_PROTOTYPE_METHOD(t, "setVersion", SetVersion);
NODE_SET_PROTOTYPE_METHOD(t, "getName", GetName);
NODE_SET_PROTOTYPE_METHOD(t, "setName", SetName);
target->Set(v8::String::NewSymbol("Application"), t->GetFunction()); target->Set(v8::String::NewSymbol("Application"), t->GetFunction());

View file

@ -40,6 +40,9 @@ class App : public EventEmitter,
static v8::Handle<v8::Value> Terminate(const v8::Arguments &args); static v8::Handle<v8::Value> Terminate(const v8::Arguments &args);
static v8::Handle<v8::Value> Focus(const v8::Arguments &args); static v8::Handle<v8::Value> Focus(const v8::Arguments &args);
static v8::Handle<v8::Value> GetVersion(const v8::Arguments &args); static v8::Handle<v8::Value> GetVersion(const v8::Arguments &args);
static v8::Handle<v8::Value> SetVersion(const v8::Arguments &args);
static v8::Handle<v8::Value> GetName(const v8::Arguments &args);
static v8::Handle<v8::Value> SetName(const v8::Arguments &args);
static v8::Handle<v8::Value> AppendSwitch(const v8::Arguments &args); static v8::Handle<v8::Value> AppendSwitch(const v8::Arguments &args);
static v8::Handle<v8::Value> AppendArgument(const v8::Arguments &args); static v8::Handle<v8::Value> AppendArgument(const v8::Arguments &args);

View file

@ -576,16 +576,17 @@ v8::Handle<v8::Value> Window::IsCrashed(const v8::Arguments &args) {
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) { v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
UNWRAP_WINDOW_AND_CHECK; UNWRAP_WINDOW_AND_CHECK;
std::string url; GURL url;
if (!FromV8Arguments(args, &url)) if (!FromV8Arguments(args, &url))
return node::ThrowTypeError("Bad argument"); return node::ThrowTypeError("Bad argument");
NavigationController& controller = NavigationController& controller =
self->window_->GetWebContents()->GetController(); self->window_->GetWebContents()->GetController();
controller.LoadURL(GURL(url),
content::Referrer(), content::NavigationController::LoadURLParams params(url);
content::PAGE_TRANSITION_AUTO_TOPLEVEL, params.transition_type = content::PAGE_TRANSITION_TYPED;
std::string()); params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
controller.LoadURLWithParams(params);
return v8::Undefined(); return v8::Undefined();
} }
@ -596,9 +597,9 @@ v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
NavigationController& controller = NavigationController& controller =
self->window_->GetWebContents()->GetController(); self->window_->GetWebContents()->GetController();
std::string url; GURL url;
if (controller.GetActiveEntry()) if (controller.GetActiveEntry())
url = controller.GetActiveEntry()->GetVirtualURL().spec(); url = controller.GetActiveEntry()->GetVirtualURL();
return ToV8Value(url); return ToV8Value(url);
} }

View file

@ -59,5 +59,15 @@ catch error
packagePath = path.join process.resourcesPath, 'browser', 'default_app' packagePath = path.join process.resourcesPath, 'browser', 'default_app'
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))) packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
# Set application's version.
app = require 'app'
app.setVersion packageJson.version if packageJson.version?
# Set application's name.
if packageJson.productName?
app.setName packageJson.productName
else if packageJson.name?
app.setName packageJson.name
# Finally load app's main.js and transfer control to C++. # Finally load app's main.js and transfer control to C++.
require path.join(packagePath, packageJson.main) require path.join(packagePath, packageJson.main)

View file

@ -33,6 +33,34 @@ void Browser::Quit() {
window_list->CloseAllWindows(); window_list->CloseAllWindows();
} }
std::string Browser::GetVersion() const {
if (version_override_.empty()) {
std::string version = GetExecutableFileVersion();
if (!version.empty())
return version;
}
return version_override_;
}
void Browser::SetVersion(const std::string& version) {
version_override_ = version;
}
std::string Browser::GetName() const {
if (name_override_.empty()) {
std::string name = GetExecutableFileProductName();
if (!name.empty())
return name;
}
return name_override_;
}
void Browser::SetName(const std::string& name) {
name_override_ = name;
}
bool Browser::OpenFile(const std::string& file_path) { bool Browser::OpenFile(const std::string& file_path) {
bool prevent_default = false; bool prevent_default = false;
FOR_EACH_OBSERVER(BrowserObserver, FOR_EACH_OBSERVER(BrowserObserver,

View file

@ -31,7 +31,16 @@ class Browser : public WindowListObserver {
void Focus(); void Focus();
// Returns the version of the executable (or bundle). // Returns the version of the executable (or bundle).
std::string GetVersion(); std::string GetVersion() const;
// Overrides the application version.
void SetVersion(const std::string& version);
// Returns the application's name, default is just Atom-Shell.
std::string GetName() const;
// Overrides the application name.
void SetName(const std::string& name);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// Bounce the dock icon. // Bounce the dock icon.
@ -68,6 +77,12 @@ class Browser : public WindowListObserver {
bool is_quiting() const { return is_quiting_; } bool is_quiting() const { return is_quiting_; }
protected: protected:
// Returns the version of application bundle or executable file.
std::string GetExecutableFileVersion() const;
// Returns the name of application bundle or executable file.
std::string GetExecutableFileProductName() const;
// Send the will-quit message and then terminate the application. // Send the will-quit message and then terminate the application.
void NotifyAndTerminate(); void NotifyAndTerminate();
@ -84,6 +99,9 @@ class Browser : public WindowListObserver {
// Observers of the browser. // Observers of the browser.
ObserverList<BrowserObserver> observers_; ObserverList<BrowserObserver> observers_;
std::string version_override_;
std::string name_override_;
DISALLOW_COPY_AND_ASSIGN(Browser); DISALLOW_COPY_AND_ASSIGN(Browser);
}; };

View file

@ -19,12 +19,18 @@ void Browser::Focus() {
[[AtomApplication sharedApplication] activateIgnoringOtherApps:YES]; [[AtomApplication sharedApplication] activateIgnoringOtherApps:YES];
} }
std::string Browser::GetVersion() { std::string Browser::GetExecutableFileVersion() const {
NSDictionary* infoDictionary = base::mac::OuterBundle().infoDictionary; NSDictionary* infoDictionary = base::mac::OuterBundle().infoDictionary;
NSString *version = [infoDictionary objectForKey:@"CFBundleVersion"]; NSString *version = [infoDictionary objectForKey:@"CFBundleVersion"];
return base::SysNSStringToUTF8(version); return base::SysNSStringToUTF8(version);
} }
std::string Browser::GetExecutableFileProductName() const {
NSDictionary* infoDictionary = base::mac::OuterBundle().infoDictionary;
NSString *version = [infoDictionary objectForKey:@"CFBundleName"];
return base::SysNSStringToUTF8(version);
}
void Browser::CancelQuit() { void Browser::CancelQuit() {
[[AtomApplication sharedApplication] replyToApplicationShouldTerminate:NO]; [[AtomApplication sharedApplication] replyToApplicationShouldTerminate:NO];
} }

View file

@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "common/atom_version.h"
namespace atom { namespace atom {
@ -43,7 +44,7 @@ void Browser::Focus() {
EnumWindows(&WindowsEnumerationHandler, reinterpret_cast<LPARAM>(&pid)); EnumWindows(&WindowsEnumerationHandler, reinterpret_cast<LPARAM>(&pid));
} }
std::string Browser::GetVersion() { std::string Browser::GetExecutableFileVersion() const {
base::FilePath path; base::FilePath path;
if (PathService::Get(base::FILE_EXE, &path)) { if (PathService::Get(base::FILE_EXE, &path)) {
scoped_ptr<FileVersionInfo> version_info( scoped_ptr<FileVersionInfo> version_info(
@ -51,7 +52,18 @@ std::string Browser::GetVersion() {
return UTF16ToUTF8(version_info->product_version()); return UTF16ToUTF8(version_info->product_version());
} }
return ""; return ATOM_VERSION_STRING;
}
std::string Browser::GetExecutableFileProductName() const {
base::FilePath path;
if (PathService::Get(base::FILE_EXE, &path)) {
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfo(path));
return UTF16ToUTF8(version_info->product_name());
}
return "Atom-Shell";
} }
void Browser::CancelQuit() { void Browser::CancelQuit() {

View file

@ -1,5 +1,5 @@
{ {
"name": "atom", "name": "atom-shell-default-app",
"version": "0.1.0", "version": "0.1.0",
"main": "main.js", "main": "main.js",
"dependencies": { "dependencies": {

View file

@ -8,6 +8,7 @@
#include "base/file_util.h" #include "base/file_util.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents.h"
@ -16,6 +17,7 @@
#include "browser/atom_browser_context.h" #include "browser/atom_browser_context.h"
#include "browser/atom_browser_main_parts.h" #include "browser/atom_browser_main_parts.h"
#include "browser/atom_javascript_dialog_manager.h" #include "browser/atom_javascript_dialog_manager.h"
#include "browser/browser.h"
#include "browser/window_list.h" #include "browser/window_list.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/invalidate_type.h" #include "content/public/browser/invalidate_type.h"
@ -26,7 +28,9 @@
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/renderer_preferences.h"
#include "common/api/api_messages.h" #include "common/api/api_messages.h"
#include "common/atom_version.h"
#include "common/options_switches.h" #include "common/options_switches.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#include "ui/gfx/codec/png_codec.h" #include "ui/gfx/codec/png_codec.h"
@ -34,6 +38,7 @@
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
#include "webkit/glue/image_decoder.h" #include "webkit/glue/image_decoder.h"
#include "webkit/user_agent/user_agent_util.h"
using content::NavigationEntry; using content::NavigationEntry;
@ -59,6 +64,15 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
WindowList::AddWindow(this); WindowList::AddWindow(this);
// Override the user agent to contain application and atom-shell's version.
Browser* browser = Browser::Get();
std::string product_name = base::StringPrintf(
"%s/%s Atom-Shell/" ATOM_VERSION_STRING,
browser->GetName().c_str(),
browser->GetVersion().c_str());
web_contents->GetMutableRendererPrefs()->user_agent_override =
webkit_glue::BuildUserAgentFromProduct(product_name);
// Get notified of title updated message. // Get notified of title updated message.
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
content::Source<content::WebContents>(web_contents)); content::Source<content::WebContents>(web_contents));

View file

@ -12,6 +12,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/string16.h" #include "base/string16.h"
#include "browser/api/atom_api_window.h" #include "browser/api/atom_api_window.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
@ -36,6 +37,11 @@ struct FromV8Value {
return string16(reinterpret_cast<const char16*>(*s), s.length()); return string16(reinterpret_cast<const char16*>(*s), s.length());
} }
operator GURL() {
std::string str = FromV8Value(value_);
return GURL(str);
}
operator base::FilePath() { operator base::FilePath() {
return base::FilePath::FromUTF8Unsafe(FromV8Value(value_)); return base::FilePath::FromUTF8Unsafe(FromV8Value(value_));
} }
@ -116,6 +122,10 @@ inline v8::Handle<v8::Value> ToV8Value(const string16& s) {
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size()); return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
} }
inline v8::Handle<v8::Value> ToV8Value(const GURL& url) {
return ToV8Value(url.spec());
}
inline v8::Handle<v8::Value> ToV8Value(const base::FilePath& path) { inline v8::Handle<v8::Value> ToV8Value(const base::FilePath& path) {
std::string path_string(path.AsUTF8Unsafe()); std::string path_string(path.AsUTF8Unsafe());
return v8::String::New(path_string.data(), path_string.size()); return v8::String::New(path_string.data(), path_string.size());
@ -159,6 +169,11 @@ bool V8ValueCanBeConvertedTo<string16>(v8::Handle<v8::Value> value) {
return V8ValueCanBeConvertedTo<std::string>(value); return V8ValueCanBeConvertedTo<std::string>(value);
} }
template<> inline
bool V8ValueCanBeConvertedTo<GURL>(v8::Handle<v8::Value> value) {
return V8ValueCanBeConvertedTo<std::string>(value);
}
template<> inline template<> inline
bool V8ValueCanBeConvertedTo<base::FilePath>(v8::Handle<v8::Value> value) { bool V8ValueCanBeConvertedTo<base::FilePath>(v8::Handle<v8::Value> value) {
return V8ValueCanBeConvertedTo<std::string>(value); return V8ValueCanBeConvertedTo<std::string>(value);

View file

@ -77,7 +77,19 @@ code will not run.
## app.getVersion() ## app.getVersion()
Returns the version of current bundle or executable. Returns the version of loaded application, if no version is found in
application's `package.json`, the version of current bundle or executable would
be returned.
## app.getName()
Returns current application's name, the name in `package.json` would be
used.
Usually the `name` field of `package.json` is a short lowercased name, according
to the spec of npm modules. So usually you should also specify a `productName`
field, which is your application's full capitalized name, and it will be
preferred over `name` by atom-shell.
## app.getBrowserWindows() ## app.getBrowserWindows()

23
spec/api/app.coffee Normal file
View file

@ -0,0 +1,23 @@
assert = require 'assert'
app = require('remote').require 'app'
describe 'app module', ->
describe 'app.getVersion()', ->
it 'returns the version field of package.json', ->
assert.equal app.getVersion(), '0.1.0'
describe 'app.setVersion(version)', ->
it 'overrides the version', ->
assert.equal app.getVersion(), '0.1.0'
app.setVersion 'test-version'
assert.equal app.getVersion(), 'test-version'
describe 'app.getName()', ->
it 'returns the name field of package.json', ->
assert.equal app.getName(), 'atom-shell-default-app'
describe 'app.setName(name)', ->
it 'overrides the name', ->
assert.equal app.getName(), 'atom-shell-default-app'
app.setName 'test-name'
assert.equal app.getName(), 'test-name'