| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/extension_tabs_module.h" | 5 #include "chrome/browser/extensions/extension_tabs_module.h" |
| 6 | 6 |
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "chrome/browser/browser.h" | 8 #include "chrome/browser/browser.h" |
| 9 #include "chrome/browser/browser_list.h" | 9 #include "chrome/browser/browser_list.h" |
| 10 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 10 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 11 #include "chrome/browser/tab_contents/navigation_entry.h" | 11 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 12 | 12 |
| 13 // Forward declare static helper functions defined below. | 13 // Forward declare static helper functions defined below. |
| 14 static DictionaryValue* CreateWindowValue(Browser* browser); |
| 15 static ListValue* CreateTabList(Browser* browser); |
| 14 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model, | 16 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model, |
| 15 int tab_index); | 17 int tab_index); |
| 16 | |
| 17 static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, | 18 static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, |
| 18 int* tab_index); | 19 int* tab_index); |
| 19 | 20 |
| 21 // ExtensionTabUtil |
| 22 int ExtensionTabUtil::GetWindowId(const Browser* browser) { |
| 23 return browser->session_id().id(); |
| 24 } |
| 25 |
| 20 int ExtensionTabUtil::GetTabId(const TabContents* tab_contents) { | 26 int ExtensionTabUtil::GetTabId(const TabContents* tab_contents) { |
| 21 return tab_contents->controller()->session_id().id(); | 27 return tab_contents->controller()->session_id().id(); |
| 22 } | 28 } |
| 23 | 29 |
| 24 int ExtensionTabUtil::GetWindowIdOfTab(const TabContents* tab_contents) { | 30 int ExtensionTabUtil::GetWindowIdOfTab(const TabContents* tab_contents) { |
| 25 return tab_contents->controller()->window_id().id(); | 31 return tab_contents->controller()->window_id().id(); |
| 26 } | 32 } |
| 27 | 33 |
| 34 bool GetWindowsFunction::RunImpl() { |
| 35 std::set<int> window_ids; |
| 36 |
| 37 // Look for |ids| named parameter as list of id's to fetch. |
| 38 if (args_->IsType(Value::TYPE_DICTIONARY)) { |
| 39 Value *ids_value; |
| 40 if ((!static_cast<DictionaryValue*>(args_)->Get(L"ids", &ids_value)) || |
| 41 (!ids_value->IsType(Value::TYPE_LIST))) { |
| 42 DHECK(false); |
| 43 return false; |
| 44 } |
| 45 |
| 46 ListValue *window_id_list = static_cast<ListValue*>(ids_value); |
| 47 for (ListValue::iterator id = window_id_list->begin(); |
| 48 id != window_id_list->end(); ++id) { |
| 49 int window_id; |
| 50 if (!(*id)->GetAsInteger(&window_id)) { |
| 51 DCHECK(false); |
| 52 return false; |
| 53 } |
| 54 |
| 55 window_ids.insert(window_id); |
| 56 } |
| 57 } |
| 58 |
| 59 // Default to all windows. |
| 60 bool all_windows = (window_ids.size() == 0); |
| 61 |
| 62 result_.reset(new ListValue()); |
| 63 for (BrowserList::const_iterator browser = BrowserList::begin(); |
| 64 browser != BrowserList::end(); ++browser) { |
| 65 if (all_windows || (window_ids.find(ExtensionTabUtil::GetWindowId(*browser)) |
| 66 != window_ids.end())) { |
| 67 static_cast<ListValue*>(result_.get())->Append( |
| 68 CreateWindowValue(*browser)); |
| 69 } |
| 70 } |
| 71 |
| 72 return true; |
| 73 } |
| 74 |
| 28 bool GetTabsForWindowFunction::RunImpl() { | 75 bool GetTabsForWindowFunction::RunImpl() { |
| 29 if (!args_->IsType(Value::TYPE_NULL)) | 76 if (!args_->IsType(Value::TYPE_NULL)) |
| 30 return false; | 77 return false; |
| 31 | 78 |
| 32 Browser* browser = BrowserList::GetLastActive(); | 79 Browser* browser = BrowserList::GetLastActive(); |
| 33 if (!browser) | 80 if (!browser) |
| 34 return false; | 81 return false; |
| 35 | 82 |
| 36 TabStripModel* tab_strip = browser->tabstrip_model(); | 83 result_.reset(CreateTabList(browser)); |
| 37 result_.reset(new ListValue()); | |
| 38 for (int i = 0; i < tab_strip->count(); ++i) { | |
| 39 static_cast<ListValue*>(result_.get())->Append( | |
| 40 CreateTabValue(tab_strip, i)); | |
| 41 } | |
| 42 | 84 |
| 43 return true; | 85 return true; |
| 44 } | 86 } |
| 45 | 87 |
| 46 bool CreateTabFunction::RunImpl() { | 88 bool CreateTabFunction::RunImpl() { |
| 47 // TODO(aa): Do data-driven validation in JS. | 89 // TODO(aa): Do data-driven validation in JS. |
| 48 if (!args_->IsType(Value::TYPE_DICTIONARY)) | 90 if (!args_->IsType(Value::TYPE_DICTIONARY)) |
| 49 return false; | 91 return false; |
| 50 | 92 |
| 51 Browser* browser = BrowserList::GetLastActive(); | 93 Browser* browser = BrowserList::GetLastActive(); |
| 52 if (!browser) | 94 if (!browser) |
| 53 return false; | 95 return false; |
| 54 | 96 |
| 55 TabStripModel *tab_strip = browser->tabstrip_model(); | 97 TabStripModel *tab_strip = browser->tabstrip_model(); |
| 56 const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); | 98 const DictionaryValue *args = static_cast<const DictionaryValue*>(args_); |
| 57 | 99 |
| 58 // TODO(rafaelw): handle setting remaining tab properties: | 100 // TODO(rafaelw): handle setting remaining tab properties: |
| 59 // -windowId | 101 // -windowId |
| 60 // -title | 102 // -title |
| 61 // -favIconUrl | 103 // -favIconUrl |
| 62 | 104 |
| 63 std::string url; | 105 std::string url; |
| 64 args_hash->GetString(L"url", &url); | 106 args->GetString(L"url", &url); |
| 65 | 107 |
| 66 // Default to foreground for the new tab. The presence of 'selected' property | 108 // Default to foreground for the new tab. The presence of 'selected' property |
| 67 // will override this default. | 109 // will override this default. |
| 68 bool selected = true; | 110 bool selected = true; |
| 69 args_hash->GetBoolean(L"selected", &selected); | 111 args->GetBoolean(L"selected", &selected); |
| 70 | 112 |
| 71 // If index is specified, honor the value, but keep it bound to | 113 // If index is specified, honor the value, but keep it bound to |
| 72 // 0 <= index <= tab_strip->count() | 114 // 0 <= index <= tab_strip->count() |
| 73 int index = -1; | 115 int index = -1; |
| 74 args_hash->GetInteger(L"index", &index); | 116 args->GetInteger(L"index", &index); |
| 75 if (index < 0) { | 117 if (index < 0) { |
| 76 // Default insert behavior | 118 // Default insert behavior |
| 77 index = -1; | 119 index = -1; |
| 78 } | 120 } |
| 79 if (index > tab_strip->count()) { | 121 if (index > tab_strip->count()) { |
| 80 index = tab_strip->count(); | 122 index = tab_strip->count(); |
| 81 } | 123 } |
| 82 | 124 |
| 83 TabContents* contents = browser->AddTabWithURL(GURL(url), GURL(), | 125 TabContents* contents = browser->AddTabWithURL(GURL(url), GURL(), |
| 84 PageTransition::TYPED, selected, index, NULL); | 126 PageTransition::TYPED, selected, index, NULL); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 bool UpdateTabFunction::RunImpl() { | 160 bool UpdateTabFunction::RunImpl() { |
| 119 // TODO(aa): Do data-driven validation in JS. | 161 // TODO(aa): Do data-driven validation in JS. |
| 120 if (!args_->IsType(Value::TYPE_DICTIONARY)) | 162 if (!args_->IsType(Value::TYPE_DICTIONARY)) |
| 121 return false; | 163 return false; |
| 122 | 164 |
| 123 Browser* browser = BrowserList::GetLastActive(); | 165 Browser* browser = BrowserList::GetLastActive(); |
| 124 if (!browser) | 166 if (!browser) |
| 125 return false; | 167 return false; |
| 126 | 168 |
| 127 int tab_id; | 169 int tab_id; |
| 128 const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); | 170 const DictionaryValue *args = static_cast<const DictionaryValue*>(args_); |
| 129 if (!args_hash->GetInteger(L"id", &tab_id)) | 171 if (!args->GetInteger(L"id", &tab_id)) |
| 130 return false; | 172 return false; |
| 131 | 173 |
| 132 int tab_index; | 174 int tab_index; |
| 133 TabStripModel* tab_strip = browser->tabstrip_model(); | 175 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 134 // TODO(rafaelw): return an error if the tab is not found by |tab_id| | 176 // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
| 135 if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) | 177 if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
| 136 return false; | 178 return false; |
| 137 | 179 |
| 138 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); | 180 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
| 139 NavigationController* controller = tab_contents->controller(); | 181 NavigationController* controller = tab_contents->controller(); |
| 140 DCHECK(controller); | 182 DCHECK(controller); |
| 141 | 183 |
| 142 // TODO(rafaelw): handle setting remaining tab properties: | 184 // TODO(rafaelw): handle setting remaining tab properties: |
| 143 // -index | |
| 144 // -windowId | |
| 145 // -title | 185 // -title |
| 146 // -favIconUrl | 186 // -favIconUrl |
| 147 | 187 |
| 148 // Navigate the tab to a new location if the url different. | 188 // Navigate the tab to a new location if the url different. |
| 149 std::string url; | 189 std::string url; |
| 150 if (args_hash->GetString(L"url", &url)) { | 190 if (args->GetString(L"url", &url)) { |
| 151 GURL new_gurl(url); | 191 GURL new_gurl(url); |
| 152 if (new_gurl.is_valid()) { | 192 if (new_gurl.is_valid()) { |
| 153 controller->LoadURL(new_gurl, GURL(), PageTransition::TYPED); | 193 controller->LoadURL(new_gurl, GURL(), PageTransition::TYPED); |
| 154 } else { | 194 } else { |
| 155 // TODO(rafaelw): return some reasonable error? | 195 // TODO(rafaelw): return some reasonable error? |
| 156 } | 196 } |
| 157 } | 197 } |
| 158 | 198 |
| 159 bool selected; | 199 bool selected; |
| 160 // TODO(rafaelw): Setting |selected| from js doesn't make much sense. | 200 // TODO(rafaelw): Setting |selected| from js doesn't make much sense. |
| 161 // Move tab selection management up to window. | 201 // Move tab selection management up to window. |
| 162 if (args_hash->GetBoolean(L"selected", &selected) && | 202 if (args->GetBoolean(L"selected", &selected) && |
| 163 selected && | 203 selected && |
| 164 tab_strip->selected_index() != tab_index) { | 204 tab_strip->selected_index() != tab_index) { |
| 165 tab_strip->SelectTabContentsAt(tab_index, false); | 205 tab_strip->SelectTabContentsAt(tab_index, false); |
| 166 } | 206 } |
| 167 | 207 |
| 168 return true; | 208 return true; |
| 169 } | 209 } |
| 170 | 210 |
| 211 bool MoveTabFunction::RunImpl() { |
| 212 if (!args_->IsType(Value::TYPE_DICTIONARY)) |
| 213 return false; |
| 214 |
| 215 Browser* browser = BrowserList::GetLastActive(); |
| 216 if (!browser) |
| 217 return false; |
| 218 |
| 219 int tab_id; |
| 220 const DictionaryValue *args = static_cast<const DictionaryValue*>(args_); |
| 221 if (!args->GetInteger(L"id", &tab_id)) |
| 222 return false; |
| 223 |
| 224 int tab_index; |
| 225 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 226 // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
| 227 if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
| 228 return false; |
| 229 |
| 230 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
| 231 NavigationController* controller = tab_contents->controller(); |
| 232 DCHECK(controller); |
| 233 |
| 234 // TODO(rafaelw): support moving tabs between windows |
| 235 // -windowId |
| 236 |
| 237 int new_index; |
| 238 DCHECK(args->GetInteger(L"index", &new_index)); |
| 239 if (new_index < 0) { |
| 240 DCHECK(false); |
| 241 return false; |
| 242 } |
| 243 |
| 244 // Clamp move location to the last position. |
| 245 if (new_index >= tab_strip->count()) { |
| 246 new_index = tab_strip->count() - 1; |
| 247 } |
| 248 |
| 249 if (new_index != tab_index) { |
| 250 tab_strip->MoveTabContentsAt(tab_index, new_index, false); |
| 251 } |
| 252 |
| 253 return true; |
| 254 } |
| 255 |
| 171 | 256 |
| 172 bool RemoveTabFunction::RunImpl() { | 257 bool RemoveTabFunction::RunImpl() { |
| 173 // TODO(rafaelw): This should have a callback, but it can't because it could | 258 // TODO(rafaelw): This should have a callback, but it can't because it could |
| 174 // close it's own tab. | 259 // close it's own tab. |
| 175 | 260 |
| 176 if (!args_->IsType(Value::TYPE_INTEGER)) | 261 if (!args_->IsType(Value::TYPE_INTEGER)) |
| 177 return false; | 262 return false; |
| 178 | 263 |
| 179 Browser* browser = BrowserList::GetLastActive(); | 264 Browser* browser = BrowserList::GetLastActive(); |
| 180 if (!browser) | 265 if (!browser) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 192 NavigationController* controller = tab_contents->controller(); | 277 NavigationController* controller = tab_contents->controller(); |
| 193 DCHECK(controller); | 278 DCHECK(controller); |
| 194 browser->CloseContents(tab_contents); | 279 browser->CloseContents(tab_contents); |
| 195 return true; | 280 return true; |
| 196 } | 281 } |
| 197 | 282 |
| 198 return false; | 283 return false; |
| 199 } | 284 } |
| 200 | 285 |
| 201 // static helpers | 286 // static helpers |
| 287 static DictionaryValue* CreateWindowValue(Browser* browser) { |
| 288 DictionaryValue* result = new DictionaryValue(); |
| 289 result->SetInteger(L"id", ExtensionTabUtil::GetWindowId(browser)); |
| 290 result->SetBoolean(L"focused", browser->window()->IsActive()); |
| 291 gfx::Rect bounds = browser->window()->GetNormalBounds(); |
| 292 |
| 293 // TODO(rafaelw): zIndex ? |
| 294 result->SetInteger(L"left", bounds.x()); |
| 295 result->SetInteger(L"top", bounds.y()); |
| 296 result->SetInteger(L"width", bounds.width()); |
| 297 result->SetInteger(L"height", bounds.height()); |
| 298 |
| 299 result->Set(L"tabs", CreateTabList(browser)); |
| 300 |
| 301 return result; |
| 302 } |
| 303 |
| 304 static ListValue* CreateTabList(Browser* browser) { |
| 305 ListValue *tab_list = new ListValue(); |
| 306 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 307 for (int i = 0; i < tab_strip->count(); ++i) { |
| 308 tab_list->Append(CreateTabValue(tab_strip, i)); |
| 309 } |
| 310 |
| 311 return tab_list; |
| 312 } |
| 313 |
| 202 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip, | 314 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip, |
| 203 int tab_index) { | 315 int tab_index) { |
| 204 TabContents* contents = tab_strip->GetTabContentsAt(tab_index); | 316 TabContents* contents = tab_strip->GetTabContentsAt(tab_index); |
| 205 NavigationController* controller = contents->controller(); | 317 NavigationController* controller = contents->controller(); |
| 206 DCHECK(controller); // TODO(aa): Is this a valid assumption? | 318 DCHECK(controller); // TODO(aa): Is this a valid assumption? |
| 207 | 319 |
| 208 DictionaryValue* result = new DictionaryValue(); | 320 DictionaryValue* result = new DictionaryValue(); |
| 209 result->SetInteger(L"id", ExtensionTabUtil::GetTabId(contents)); | 321 result->SetInteger(L"id", ExtensionTabUtil::GetTabId(contents)); |
| 210 result->SetInteger(L"index", tab_index); | 322 result->SetInteger(L"index", tab_index); |
| 211 result->SetInteger(L"windowId", ExtensionTabUtil::GetWindowIdOfTab(contents)); | 323 result->SetInteger(L"windowId", ExtensionTabUtil::GetWindowIdOfTab(contents)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 229 NavigationController* controller = tab_contents->controller(); | 341 NavigationController* controller = tab_contents->controller(); |
| 230 DCHECK(controller); // TODO(aa): Is this a valid assumption? | 342 DCHECK(controller); // TODO(aa): Is this a valid assumption? |
| 231 | 343 |
| 232 if (controller->session_id().id() == tab_id) { | 344 if (controller->session_id().id() == tab_id) { |
| 233 *tab_index = i; | 345 *tab_index = i; |
| 234 return true; | 346 return true; |
| 235 } | 347 } |
| 236 } | 348 } |
| 237 return false; | 349 return false; |
| 238 } | 350 } |
| OLD | NEW |