Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: chrome/browser/extensions/api/tabs/tabs_api.cc

Issue 245933002: Initial implementation of chrome.browser.openTab. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/tabs/tabs_api.h" 5 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #include "content/public/browser/render_process_host.h" 61 #include "content/public/browser/render_process_host.h"
62 #include "content/public/browser/render_view_host.h" 62 #include "content/public/browser/render_view_host.h"
63 #include "content/public/browser/render_widget_host_view.h" 63 #include "content/public/browser/render_widget_host_view.h"
64 #include "content/public/browser/web_contents.h" 64 #include "content/public/browser/web_contents.h"
65 #include "content/public/browser/web_contents_view.h" 65 #include "content/public/browser/web_contents_view.h"
66 #include "content/public/common/url_constants.h" 66 #include "content/public/common/url_constants.h"
67 #include "extensions/browser/extension_function_dispatcher.h" 67 #include "extensions/browser/extension_function_dispatcher.h"
68 #include "extensions/browser/extension_function_util.h" 68 #include "extensions/browser/extension_function_util.h"
69 #include "extensions/browser/extension_host.h" 69 #include "extensions/browser/extension_host.h"
70 #include "extensions/browser/file_reader.h" 70 #include "extensions/browser/file_reader.h"
71 #include "extensions/common/constants.h"
72 #include "extensions/common/error_utils.h" 71 #include "extensions/common/error_utils.h"
73 #include "extensions/common/extension.h" 72 #include "extensions/common/extension.h"
74 #include "extensions/common/extension_l10n_util.h" 73 #include "extensions/common/extension_l10n_util.h"
75 #include "extensions/common/extension_messages.h" 74 #include "extensions/common/extension_messages.h"
76 #include "extensions/common/manifest_constants.h" 75 #include "extensions/common/manifest_constants.h"
77 #include "extensions/common/manifest_handlers/incognito_info.h"
78 #include "extensions/common/message_bundle.h" 76 #include "extensions/common/message_bundle.h"
79 #include "extensions/common/permissions/permissions_data.h" 77 #include "extensions/common/permissions/permissions_data.h"
80 #include "extensions/common/user_script.h" 78 #include "extensions/common/user_script.h"
81 #include "skia/ext/image_operations.h" 79 #include "skia/ext/image_operations.h"
82 #include "skia/ext/platform_canvas.h" 80 #include "skia/ext/platform_canvas.h"
83 #include "third_party/skia/include/core/SkBitmap.h" 81 #include "third_party/skia/include/core/SkBitmap.h"
84 #include "ui/base/models/list_selection_model.h" 82 #include "ui/base/models/list_selection_model.h"
85 #include "ui/base/ui_base_types.h" 83 #include "ui/base/ui_base_types.h"
86 84
87 #if defined(USE_ASH) 85 #if defined(USE_ASH)
(...skipping 13 matching lines...) Expand all
101 namespace extensions { 99 namespace extensions {
102 100
103 namespace windows = api::windows; 101 namespace windows = api::windows;
104 namespace keys = tabs_constants; 102 namespace keys = tabs_constants;
105 namespace tabs = api::tabs; 103 namespace tabs = api::tabs;
106 104
107 using api::tabs::InjectDetails; 105 using api::tabs::InjectDetails;
108 106
109 namespace { 107 namespace {
110 108
111 // |error_message| can optionally be passed in a will be set with an appropriate
112 // message if the window cannot be found by id.
113 Browser* GetBrowserInProfileWithId(Profile* profile,
114 const int window_id,
115 bool include_incognito,
116 std::string* error_message) {
117 Profile* incognito_profile =
118 include_incognito && profile->HasOffTheRecordProfile() ?
119 profile->GetOffTheRecordProfile() : NULL;
120 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
121 Browser* browser = *it;
122 if ((browser->profile() == profile ||
123 browser->profile() == incognito_profile) &&
124 ExtensionTabUtil::GetWindowId(browser) == window_id &&
125 browser->window()) {
126 return browser;
127 }
128 }
129
130 if (error_message)
131 *error_message = ErrorUtils::FormatErrorMessage(
132 keys::kWindowNotFoundError, base::IntToString(window_id));
133
134 return NULL;
135 }
136
137 bool GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function, 109 bool GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function,
138 int window_id, 110 int window_id,
139 Browser** browser) { 111 Browser** browser) {
140 if (window_id == extension_misc::kCurrentWindowId) { 112 std::string error;
141 *browser = function->GetCurrentBrowser(); 113 Browser* result;
142 if (!(*browser) || !(*browser)->window()) { 114 result =
143 function->SetError(keys::kNoCurrentWindowError); 115 ExtensionTabUtil::GetBrowserFromWindowID(function, window_id, &error);
144 return false; 116 if (!result) {
145 } 117 function->SetError(error);
146 } else { 118 return false;
147 std::string error;
148 *browser = GetBrowserInProfileWithId(function->GetProfile(),
149 window_id,
150 function->include_incognito(),
151 &error);
152 if (!*browser) {
153 function->SetError(error);
154 return false;
155 }
156 } 119 }
120
121 *browser = result;
157 return true; 122 return true;
158 } 123 }
159 124
160 // |error_message| can optionally be passed in and will be set with an 125 // |error_message| can optionally be passed in and will be set with an
161 // appropriate message if the tab cannot be found by id. 126 // appropriate message if the tab cannot be found by id.
162 bool GetTabById(int tab_id, 127 bool GetTabById(int tab_id,
163 Profile* profile, 128 Profile* profile,
164 bool include_incognito, 129 bool include_incognito,
165 Browser** browser, 130 Browser** browser,
166 TabStripModel** tab_strip, 131 TabStripModel** tab_strip,
(...skipping 11 matching lines...) Expand all
178 return false; 143 return false;
179 } 144 }
180 145
181 // Returns true if either |boolean| is a null pointer, or if |*boolean| and 146 // Returns true if either |boolean| is a null pointer, or if |*boolean| and
182 // |value| are equal. This function is used to check if a tab's parameters match 147 // |value| are equal. This function is used to check if a tab's parameters match
183 // those of the browser. 148 // those of the browser.
184 bool MatchesBool(bool* boolean, bool value) { 149 bool MatchesBool(bool* boolean, bool value) {
185 return !boolean || *boolean == value; 150 return !boolean || *boolean == value;
186 } 151 }
187 152
153 template <typename T>
154 void AssignOptionalValue(const scoped_ptr<T>& source,
155 scoped_ptr<T>& destination) {
156 if (source.get()) {
157 destination.reset(new T(*source.get()));
158 }
159 }
160
188 } // namespace 161 } // namespace
189 162
190 // Windows --------------------------------------------------------------------- 163 // Windows ---------------------------------------------------------------------
191 164
192 bool WindowsGetFunction::RunSync() { 165 bool WindowsGetFunction::RunSync() {
193 scoped_ptr<windows::Get::Params> params(windows::Get::Params::Create(*args_)); 166 scoped_ptr<windows::Get::Params> params(windows::Get::Params::Create(*args_));
194 EXTENSION_FUNCTION_VALIDATE(params.get()); 167 EXTENSION_FUNCTION_VALIDATE(params.get());
195 168
196 bool populate_tabs = false; 169 bool populate_tabs = false;
197 if (params->get_info.get() && params->get_info->populate.get()) 170 if (params->get_info.get() && params->get_info->populate.get())
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 870 }
898 871
899 SetResult(result); 872 SetResult(result);
900 return true; 873 return true;
901 } 874 }
902 875
903 bool TabsCreateFunction::RunSync() { 876 bool TabsCreateFunction::RunSync() {
904 scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_)); 877 scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_));
905 EXTENSION_FUNCTION_VALIDATE(params.get()); 878 EXTENSION_FUNCTION_VALIDATE(params.get());
906 879
907 // windowId defaults to "current" window. 880 ExtensionTabUtil::OpenTabParams options;
908 int window_id = extension_misc::kCurrentWindowId; 881 AssignOptionalValue(params->create_properties.window_id, options.window_id);
909 if (params->create_properties.window_id.get()) 882 AssignOptionalValue(params->create_properties.opener_tab_id,
910 window_id = *params->create_properties.window_id; 883 options.opener_tab_id);
884 AssignOptionalValue(params->create_properties.selected, options.active);
885 // The 'active' property has replaced the 'selected' property.
886 AssignOptionalValue(params->create_properties.active, options.active);
887 AssignOptionalValue(params->create_properties.pinned, options.pinned);
888 AssignOptionalValue(params->create_properties.index, options.index);
889 AssignOptionalValue(params->create_properties.url, options.url);
911 890
912 Browser* browser = NULL; 891 std::string error;
913 if (!GetBrowserFromWindowID(this, window_id, &browser)) 892 scoped_ptr<base::DictionaryValue> result(
914 return false; 893 ExtensionTabUtil::OpenTab(this, options, &error));
915 894 if (!result) {
916 // Ensure the selected browser is tabbed. 895 SetError(error);
917 if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser())
918 browser = chrome::FindTabbedBrowser(
919 GetProfile(), include_incognito(), browser->host_desktop_type());
920
921 if (!browser || !browser->window())
922 return false;
923
924 // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that
925 // represents the active tab.
926 WebContents* opener = NULL;
927 if (params->create_properties.opener_tab_id.get()) {
928 int opener_id = *params->create_properties.opener_tab_id;
929
930 if (!ExtensionTabUtil::GetTabById(opener_id,
931 GetProfile(),
932 include_incognito(),
933 NULL,
934 NULL,
935 &opener,
936 NULL)) {
937 return false;
938 }
939 }
940
941 // TODO(rafaelw): handle setting remaining tab properties:
942 // -title
943 // -favIconUrl
944
945 std::string url_string;
946 GURL url;
947 if (params->create_properties.url.get()) {
948 url_string = *params->create_properties.url;
949 url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string,
950 GetExtension());
951 if (!url.is_valid()) {
952 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
953 url_string);
954 return false;
955 }
956 }
957
958 // Don't let extensions crash the browser or renderers.
959 if (ExtensionTabUtil::IsCrashURL(url)) {
960 error_ = keys::kNoCrashBrowserError;
961 return false; 896 return false;
962 } 897 }
963 898
964 // Default to foreground for the new tab. The presence of 'selected' property
965 // will override this default. This property is deprecated ('active' should
966 // be used instead).
967 bool active = true;
968 if (params->create_properties.selected.get())
969 active = *params->create_properties.selected;
970
971 // The 'active' property has replaced the 'selected' property.
972 if (params->create_properties.active.get())
973 active = *params->create_properties.active;
974
975 // Default to not pinning the tab. Setting the 'pinned' property to true
976 // will override this default.
977 bool pinned = false;
978 if (params->create_properties.pinned.get())
979 pinned = *params->create_properties.pinned;
980
981 // We can't load extension URLs into incognito windows unless the extension
982 // uses split mode. Special case to fall back to a tabbed window.
983 if (url.SchemeIs(kExtensionScheme) &&
984 !IncognitoInfo::IsSplitMode(GetExtension()) &&
985 browser->profile()->IsOffTheRecord()) {
986 Profile* profile = browser->profile()->GetOriginalProfile();
987 chrome::HostDesktopType desktop_type = browser->host_desktop_type();
988
989 browser = chrome::FindTabbedBrowser(profile, false, desktop_type);
990 if (!browser) {
991 browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
992 profile, desktop_type));
993 browser->window()->Show();
994 }
995 }
996
997 // If index is specified, honor the value, but keep it bound to
998 // -1 <= index <= tab_strip->count() where -1 invokes the default behavior.
999 int index = -1;
1000 if (params->create_properties.index.get())
1001 index = *params->create_properties.index;
1002
1003 TabStripModel* tab_strip = browser->tab_strip_model();
1004
1005 index = std::min(std::max(index, -1), tab_strip->count());
1006
1007 int add_types = active ? TabStripModel::ADD_ACTIVE :
1008 TabStripModel::ADD_NONE;
1009 add_types |= TabStripModel::ADD_FORCE_INDEX;
1010 if (pinned)
1011 add_types |= TabStripModel::ADD_PINNED;
1012 chrome::NavigateParams navigate_params(
1013 browser, url, content::PAGE_TRANSITION_LINK);
1014 navigate_params.disposition =
1015 active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
1016 navigate_params.tabstrip_index = index;
1017 navigate_params.tabstrip_add_types = add_types;
1018 chrome::Navigate(&navigate_params);
1019
1020 // The tab may have been created in a different window, so make sure we look
1021 // at the right tab strip.
1022 tab_strip = navigate_params.browser->tab_strip_model();
1023 int new_index = tab_strip->GetIndexOfWebContents(
1024 navigate_params.target_contents);
1025 if (opener)
1026 tab_strip->SetOpenerOfWebContentsAt(new_index, opener);
1027
1028 if (active)
1029 navigate_params.target_contents->GetView()->SetInitialFocus();
1030
1031 // Return data about the newly created tab. 899 // Return data about the newly created tab.
1032 if (has_callback()) { 900 if (has_callback()) {
1033 SetResult(ExtensionTabUtil::CreateTabValue( 901 SetResult(result.release());
1034 navigate_params.target_contents,
1035 tab_strip, new_index, GetExtension()));
1036 } 902 }
1037
1038 return true; 903 return true;
1039 } 904 }
1040 905
1041 bool TabsDuplicateFunction::RunSync() { 906 bool TabsDuplicateFunction::RunSync() {
1042 scoped_ptr<tabs::Duplicate::Params> params( 907 scoped_ptr<tabs::Duplicate::Params> params(
1043 tabs::Duplicate::Params::Create(*args_)); 908 tabs::Duplicate::Params::Create(*args_));
1044 EXTENSION_FUNCTION_VALIDATE(params.get()); 909 EXTENSION_FUNCTION_VALIDATE(params.get());
1045 int tab_id = params->tab_id; 910 int tab_id = params->tab_id;
1046 911
1047 Browser* browser = NULL; 912 Browser* browser = NULL;
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 execute_tab_id_ = tab_id; 1736 execute_tab_id_ = tab_id;
1872 details_ = details.Pass(); 1737 details_ = details.Pass();
1873 return true; 1738 return true;
1874 } 1739 }
1875 1740
1876 bool TabsInsertCSSFunction::ShouldInsertCSS() const { 1741 bool TabsInsertCSSFunction::ShouldInsertCSS() const {
1877 return true; 1742 return true;
1878 } 1743 }
1879 1744
1880 } // namespace extensions 1745 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/browser/browser_apitest.cc ('k') | chrome/browser/extensions/extension_tab_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698