Chromium Code Reviews| 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 |