summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/app_window/app_window_api.cc
blob: 97dcd1c195d11743b658a43e703b42493dce3964 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/app_window/app_window_api.h"

#include "base/command_line.h"
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/extensions/window_controller.h"
#include "chrome/browser/ui/extensions/shell_window.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/app_window.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/rect.h"

namespace app_window = extensions::api::app_window;
namespace Create = app_window::Create;

namespace extensions {

namespace app_window_constants {
const char kInvalidWindowId[] =
    "The window id can not be more than 256 characters long.";
};

const char kNoneFrameOption[] = "none";
const char kHtmlFrameOption[] = "experimental-html";

bool AppWindowCreateFunction::RunImpl() {
  scoped_ptr<Create::Params> params(Create::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params.get());

  GURL url = GetExtension()->GetResourceURL(params->url);

  bool inject_html_titlebar = false;

  // TODO(jeremya): figure out a way to pass the opening WebContents through to
  // ShellWindow::Create so we can set the opener at create time rather than
  // with a hack in AppWindowCustomBindings::GetView().
  ShellWindow::CreateParams create_params;
  app_window::CreateWindowOptions* options = params->options.get();
  if (options) {
    if (options->id.get()) {
      // TODO(mek): use URL if no id specified?
      // Limit length of id to 256 characters.
      if (options->id->length() > 256) {
        error_ = app_window_constants::kInvalidWindowId;
        return false;
      }

      create_params.window_key = *options->id;
    }

    if (options->default_width.get())
      create_params.bounds.set_width(*options->default_width.get());
    if (options->default_height.get())
      create_params.bounds.set_height(*options->default_height.get());
    if (options->default_left.get())
      create_params.bounds.set_x(*options->default_left.get());
    if (options->default_top.get())
      create_params.bounds.set_y(*options->default_top.get());


    if (options->width.get() || options->height.get()) {
      if (options->width.get())
        create_params.bounds.set_width(*options->width.get());
      if (options->height.get())
        create_params.bounds.set_height(*options->height.get());
      create_params.restore_size = false;
    }

    if (options->left.get() || options->top.get()) {
      if (options->left.get())
        create_params.bounds.set_x(*options->left.get());
      if (options->top.get())
        create_params.bounds.set_y(*options->top.get());
      create_params.restore_position = false;
    }

    if (options->frame.get()) {
      if (*options->frame == kHtmlFrameOption &&
          CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kEnableExperimentalExtensionApis)) {
        create_params.frame = ShellWindow::CreateParams::FRAME_NONE;
        inject_html_titlebar = true;
      } else if (*options->frame == kNoneFrameOption) {
        create_params.frame = ShellWindow::CreateParams::FRAME_NONE;
      } else {
        create_params.frame = ShellWindow::CreateParams::FRAME_CHROME;
      }
    }

    gfx::Size& minimum_size = create_params.minimum_size;
    if (options->min_width.get())
      minimum_size.set_width(*options->min_width);
    if (options->min_height.get())
      minimum_size.set_height(*options->min_height);
    gfx::Size& maximum_size = create_params.maximum_size;
    if (options->max_width.get())
      maximum_size.set_width(*options->max_width);
    if (options->max_height.get())
      maximum_size.set_height(*options->max_height);
    // In the case that minimum size > maximum size, we consider the minimum
    // size to be more important.
    if (maximum_size.width() && maximum_size.width() < minimum_size.width())
      maximum_size.set_width(minimum_size.width());
    if (maximum_size.height() && maximum_size.height() < minimum_size.height())
      maximum_size.set_height(minimum_size.height());

    if (maximum_size.width() &&
        create_params.bounds.width() > maximum_size.width())
      create_params.bounds.set_width(maximum_size.width());
    if (create_params.bounds.width() < minimum_size.width())
      create_params.bounds.set_width(minimum_size.width());

    if (maximum_size.height() &&
        create_params.bounds.height() > maximum_size.height())
      create_params.bounds.set_height(maximum_size.height());
    if (create_params.bounds.height() < minimum_size.height())
      create_params.bounds.set_height(minimum_size.height());
  }
  ShellWindow* shell_window =
      ShellWindow::Create(profile(), GetExtension(), url, create_params);
  shell_window->GetBaseWindow()->Show();

  content::WebContents* created_contents = shell_window->web_contents();
  int view_id = created_contents->GetRenderViewHost()->GetRoutingID();

  base::DictionaryValue* result = new base::DictionaryValue;
  result->Set("viewId", base::Value::CreateIntegerValue(view_id));
  result->Set("injectTitlebar",
      base::Value::CreateBooleanValue(inject_html_titlebar));
  result->Set("id", base::Value::CreateStringValue(shell_window->window_key()));
  SetResult(result);
  return true;
}

}  // namespace extensions