Index: chrome/browser/extensions/api/app_window/app_window_api.cc |
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc |
index 7f0006d1a03bbe6a92c0a2ac709224f780704a9f..bcdbaac617744d0c2742a99784620a5252ec9a91 100644 |
--- a/chrome/browser/extensions/api/app_window/app_window_api.cc |
+++ b/chrome/browser/extensions/api/app_window/app_window_api.cc |
@@ -9,6 +9,7 @@ |
#include "apps/app_window_registry.h" |
#include "apps/ui/native_app_window.h" |
#include "base/command_line.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/time/time.h" |
#include "base/values.h" |
#include "chrome/browser/app_mode/app_mode_utils.h" |
@@ -26,6 +27,7 @@ |
#include "content/public/common/url_constants.h" |
#include "extensions/browser/extensions_browser_client.h" |
#include "extensions/common/switches.h" |
+#include "third_party/skia/include/core/SkColor.h" |
#include "ui/base/ui_base_types.h" |
#include "ui/gfx/rect.h" |
#include "url/gurl.h" |
@@ -46,10 +48,16 @@ namespace extensions { |
namespace app_window_constants { |
const char kInvalidWindowId[] = |
"The window id can not be more than 256 characters long."; |
-} |
+const char kInvalidColorSpecification[] = |
+ "The color specification could not be parsed."; |
+const char kInvalidChannelForFrameOptions[] = |
+ "frameOptions is only available in dev channel."; |
+const char kFrameOptionsAndFrame[] = |
+ "Only one of frame and frameOptions can be supplied."; |
+const char kColorWithFrameNone[] = "Windows with no frame cannot have a color."; |
+} // namespace app_window_constants |
const char kNoneFrameOption[] = "none"; |
-const char kHtmlFrameOption[] = "experimental-html"; |
namespace { |
@@ -82,6 +90,40 @@ class DevToolsRestorer : public base::RefCounted<DevToolsRestorer> { |
scoped_refptr<AppWindowCreateFunction> delayed_create_function_; |
}; |
+bool ParseCSSColorString(const std::string& color_string, SkColor* result) { |
Matt Giuca
2014/02/18 06:03:18
It's kind of surprising that there isn't already s
benwells
2014/02/18 07:47:25
Yeah I forgot I had copy pasted this :-/
Using th
|
+ std::string formatted_color = "#"; |
Matt Giuca
2014/02/18 06:03:18
Nit: Why does formatted_color need to start with a
|
+ // Check the string for incorrect formatting. |
+ if (color_string[0] != '#') |
Matt Giuca
2014/02/18 06:03:18
if (color_string.empty() || ...) (potential buffer
benwells
2014/02/18 07:47:25
Done.
|
+ return false; |
+ |
+ // Convert the string from #FFF format to #FFFFFF format. |
+ if (color_string.length() == 4) { |
+ for (size_t i = 1; i < color_string.length(); i++) { |
Matt Giuca
2014/02/18 06:03:18
Why not: i < 4
Also: ++i
benwells
2014/02/18 07:47:25
Done.
|
+ formatted_color += color_string[i]; |
+ formatted_color += color_string[i]; |
+ } |
+ } else { |
Matt Giuca
2014/02/18 06:03:18
How about:
// You could even move this first, sinc
benwells
2014/02/18 07:47:25
Done. I think a DCHECK is unwarranted.
|
+ formatted_color = color_string; |
+ } |
+ |
+ if (formatted_color.length() != 7) |
+ return false; |
+ |
+ // Convert the string to an integer and make sure it is in the correct value |
+ // range. |
+ int color_ints[3] = {0}; |
Matt Giuca
2014/02/18 06:03:18
Use HexStringToBytes instead of manually looping.
benwells
2014/02/18 07:47:25
Done.
|
+ for (int i = 0; i < 3; i++) { |
Matt Giuca
2014/02/18 06:03:18
Nit: ++i
benwells
2014/02/18 07:47:25
Done.
|
+ if (!base::HexStringToInt(formatted_color.substr(1 + (2 * i), 2), |
+ color_ints + i)) |
Matt Giuca
2014/02/18 06:03:18
Nit: &color_ints[i]
|
+ return false; |
+ if (color_ints[i] > 255 || color_ints[i] < 0) |
Matt Giuca
2014/02/18 06:03:18
This should be a DCHECK, since it is not physicall
|
+ return false; |
+ } |
+ |
+ *result = SkColorSetARGB(255, color_ints[0], color_ints[1], color_ints[2]); |
+ return true; |
+} |
+ |
} // namespace |
void AppWindowCreateFunction::SendDelayedResponse() { |
@@ -105,8 +147,6 @@ bool AppWindowCreateFunction::RunImpl() { |
url = absolute; |
} |
- bool inject_html_titlebar = false; |
- |
// TODO(jeremya): figure out a way to pass the opening WebContents through to |
// AppWindow::Create so we can set the opener at create time rather than |
// with a hack in AppWindowCustomBindings::GetView(). |
@@ -152,6 +192,7 @@ bool AppWindowCreateFunction::RunImpl() { |
result->Set("viewId", new base::FundamentalValue(view_id)); |
window->GetSerializedState(result); |
result->SetBoolean("existingWindow", true); |
+ // TODO(benwells): Remove HTML titlebar injection. |
Matt Giuca
2014/02/18 06:03:18
I think that removing HTML titlebar injection shou
benwells
2014/02/18 07:47:25
Done.
|
result->SetBoolean("injectTitlebar", false); |
SetResult(result); |
SendResponse(true); |
@@ -199,19 +240,8 @@ bool AppWindowCreateFunction::RunImpl() { |
} |
} |
- if (options->frame.get()) { |
- if (*options->frame == kHtmlFrameOption && |
- (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || |
- CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kEnableExperimentalExtensionApis))) { |
- create_params.frame = AppWindow::FRAME_NONE; |
- inject_html_titlebar = true; |
- } else if (*options->frame == kNoneFrameOption) { |
- create_params.frame = AppWindow::FRAME_NONE; |
- } else { |
- create_params.frame = AppWindow::FRAME_CHROME; |
- } |
- } |
+ if (!GetFrameOptions(*options, &create_params)) |
+ return false; |
if (options->transparent_background.get() && |
(GetExtension()->HasAPIPermission(APIPermission::kExperimental) || |
@@ -262,6 +292,8 @@ bool AppWindowCreateFunction::RunImpl() { |
} |
} |
+ UpdateFrameOptionsForChannel(&create_params); |
+ |
create_params.creator_process_id = |
render_view_host_->GetProcess()->GetID(); |
@@ -281,8 +313,8 @@ bool AppWindowCreateFunction::RunImpl() { |
base::DictionaryValue* result = new base::DictionaryValue; |
result->Set("viewId", new base::FundamentalValue(view_id)); |
- result->Set("injectTitlebar", |
- new base::FundamentalValue(inject_html_titlebar)); |
+ // TODO(benwells): Remove HTML titlebar injection. |
+ result->Set("injectTitlebar", new base::FundamentalValue(false)); |
result->Set("id", new base::StringValue(app_window->window_key())); |
app_window->GetSerializedState(result); |
SetResult(result); |
@@ -297,4 +329,65 @@ bool AppWindowCreateFunction::RunImpl() { |
return true; |
} |
+AppWindow::Frame AppWindowCreateFunction::GetFrameFromString( |
+ const std::string& frame_string) { |
+ if (frame_string == kNoneFrameOption) |
+ return AppWindow::FRAME_NONE; |
+ |
+ return AppWindow::FRAME_CHROME; |
+} |
+ |
+bool AppWindowCreateFunction::GetFrameOptions( |
+ const app_window::CreateWindowOptions& options, |
+ AppWindow::CreateParams* create_params) { |
+ if (options.frame.get() && options.frame_options.get()) { |
+ error_ = app_window_constants::kFrameOptionsAndFrame; |
+ return false; |
+ } |
+ |
+ if (options.frame.get()) |
+ create_params->frame = GetFrameFromString(*options.frame); |
+ |
+ if (options.frame_options.get()) { |
+ if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) { |
+ app_window::FrameOptions* frame_options = options.frame_options.get(); |
+ |
+ if (frame_options->type.get()) |
+ create_params->frame = GetFrameFromString(*frame_options->type); |
+ |
+ if (frame_options->color.get()) { |
+ if (create_params->frame != AppWindow::FRAME_CHROME) { |
+ error_ = app_window_constants::kColorWithFrameNone; |
+ return false; |
+ } |
+ |
+ if (ParseCSSColorString(*frame_options->color, |
+ &create_params->frame_color)) { |
+ create_params->has_frame_color = true; |
+ } else { |
+ error_ = app_window_constants::kInvalidColorSpecification; |
Matt Giuca
2014/02/18 06:03:18
Where does this error get displayed or sent? In yo
benwells
2014/02/18 07:47:25
It gets put in chrome.runtime.lastError. For some
|
+ return false; |
+ } |
+ } |
+ } else { |
+ error_ = app_window_constants::kInvalidChannelForFrameOptions; |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |
+ |
+void AppWindowCreateFunction::UpdateFrameOptionsForChannel( |
+ apps::AppWindow::CreateParams* create_params) { |
+ if (create_params->frame == AppWindow::FRAME_CHROME && |
+ GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) { |
+ // If not on trunk or dev channel, always use the standard white frame. This |
Matt Giuca
2014/02/18 06:03:18
Can you change the second sentence into a TODO(ben
benwells
2014/02/18 07:47:25
Done.
|
+ // code will be remove once we get agreement to use the new native style |
+ // frame. |
+ create_params->has_frame_color = true; |
+ create_params->frame_color = SK_ColorWHITE; |
+ } |
+} |
+ |
} // namespace extensions |