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* CreateTabValue(TabStripModel* tab_strip_model, | 14 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model, |
15 int tab_index); | 15 int tab_index); |
16 | 16 |
| 17 static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, |
| 18 int* tab_index); |
| 19 |
17 bool GetTabsForWindowFunction::RunImpl() { | 20 bool GetTabsForWindowFunction::RunImpl() { |
18 if (!args_->IsType(Value::TYPE_NULL)) | 21 if (!args_->IsType(Value::TYPE_NULL)) |
19 return false; | 22 return false; |
20 | 23 |
21 Browser* browser = BrowserList::GetLastActive(); | 24 Browser* browser = BrowserList::GetLastActive(); |
22 if (!browser) | 25 if (!browser) |
23 return false; | 26 return false; |
24 | 27 |
25 TabStripModel* tab_strip = browser->tabstrip_model(); | 28 TabStripModel* tab_strip = browser->tabstrip_model(); |
26 result_.reset(new ListValue()); | 29 result_.reset(new ListValue()); |
27 for (int i = 0; i < tab_strip->count(); ++i) { | 30 for (int i = 0; i < tab_strip->count(); ++i) { |
28 static_cast<ListValue*>(result_.get())->Append( | 31 static_cast<ListValue*>(result_.get())->Append( |
29 CreateTabValue(tab_strip, i)); | 32 CreateTabValue(tab_strip, i)); |
30 } | 33 } |
31 | 34 |
32 return true; | 35 return true; |
33 } | 36 } |
34 | 37 |
35 bool CreateTabFunction::RunImpl() { | 38 bool CreateTabFunction::RunImpl() { |
36 // TODO(aa): Do data-driven validation in JS. | 39 // TODO(aa): Do data-driven validation in JS. |
37 if (!args_->IsType(Value::TYPE_DICTIONARY)) | 40 if (!args_->IsType(Value::TYPE_DICTIONARY)) |
38 return false; | 41 return false; |
39 | 42 |
40 Browser* browser = BrowserList::GetLastActive(); | 43 Browser* browser = BrowserList::GetLastActive(); |
41 if (!browser) | 44 if (!browser) |
42 return false; | 45 return false; |
43 | 46 |
44 // TODO(aa): Handle all the other properties of the new tab. | 47 TabStripModel *tab_strip = browser->tabstrip_model(); |
| 48 const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); |
| 49 |
| 50 // TODO(rafaelw): handle setting remaining tab properties: |
| 51 // -windowId |
| 52 // -title |
| 53 // -favIconUrl |
| 54 |
45 std::string url; | 55 std::string url; |
46 static_cast<const DictionaryValue*>(args_)->GetString(L"url", &url); | 56 args_hash->GetString(L"url", &url); |
47 browser->AddTabWithURL(GURL(url), GURL(), PageTransition::TYPED, true, -1, | 57 |
48 NULL); | 58 // Default to foreground for the new tab. The presence of 'selected' property |
| 59 // will override this default. |
| 60 bool selected = true; |
| 61 args_hash->GetBoolean(L"selected", &selected); |
| 62 |
| 63 // If index is specified, honor the value, but keep it bound to |
| 64 // 0 <= index <= tab_strip->count() |
| 65 int index = -1; |
| 66 args_hash->GetInteger(L"index", &index); |
| 67 if (index < 0) { |
| 68 // Default insert behavior |
| 69 index = -1; |
| 70 } |
| 71 if (index > tab_strip->count()) { |
| 72 index = tab_strip->count(); |
| 73 } |
| 74 |
| 75 TabContents* contents = browser->AddTabWithURL(GURL(url), GURL(), |
| 76 PageTransition::TYPED, selected, index, NULL); |
| 77 index = tab_strip->GetIndexOfTabContents(contents); |
49 | 78 |
50 // Return data about the newly created tab. | 79 // Return data about the newly created tab. |
51 if (has_callback()) | 80 if (has_callback()) |
52 result_.reset(CreateTabValue(browser->tabstrip_model(), | 81 result_.reset(CreateTabValue(tab_strip, index)); |
53 browser->tabstrip_model()->count() - 1)); | 82 |
| 83 return true; |
| 84 } |
| 85 |
| 86 bool GetTabFunction::RunImpl() { |
| 87 if (!args_->IsType(Value::TYPE_INTEGER)) |
| 88 return false; |
| 89 |
| 90 Browser* browser = BrowserList::GetLastActive(); |
| 91 if (!browser) |
| 92 return false; |
| 93 |
| 94 int tab_id; |
| 95 args_->GetAsInteger(&tab_id); |
| 96 |
| 97 int tab_index; |
| 98 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 99 // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
| 100 if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
| 101 return false; |
| 102 |
| 103 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
| 104 NavigationController* controller = tab_contents->controller(); |
| 105 DCHECK(controller); |
| 106 result_.reset(CreateTabValue(tab_strip, tab_index)); |
| 107 return true; |
| 108 } |
| 109 |
| 110 bool UpdateTabFunction::RunImpl() { |
| 111 // TODO(aa): Do data-driven validation in JS. |
| 112 if (!args_->IsType(Value::TYPE_DICTIONARY)) |
| 113 return false; |
| 114 |
| 115 Browser* browser = BrowserList::GetLastActive(); |
| 116 if (!browser) |
| 117 return false; |
| 118 |
| 119 int tab_id; |
| 120 const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); |
| 121 if (!args_hash->GetInteger(L"id", &tab_id)) |
| 122 return false; |
| 123 |
| 124 int tab_index; |
| 125 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 126 // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
| 127 if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
| 128 return false; |
| 129 |
| 130 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
| 131 NavigationController* controller = tab_contents->controller(); |
| 132 DCHECK(controller); |
| 133 |
| 134 // TODO(rafaelw): handle setting remaining tab properties: |
| 135 // -index |
| 136 // -windowId |
| 137 // -title |
| 138 // -favIconUrl |
| 139 |
| 140 // Navigate the tab to a new location if the url different. |
| 141 std::string url; |
| 142 if (args_hash->GetString(L"url", &url)) { |
| 143 GURL new_gurl(url); |
| 144 if (new_gurl.is_valid()) { |
| 145 controller->LoadURL(new_gurl, GURL(), PageTransition::TYPED); |
| 146 } else { |
| 147 // TODO(rafaelw): return some reasonable error? |
| 148 } |
| 149 } |
| 150 |
| 151 bool selected; |
| 152 // TODO(rafaelw): Setting |selected| from js doesn't make much sense. |
| 153 // Move tab selection management up to window. |
| 154 if (args_hash->GetBoolean(L"selected", &selected) && |
| 155 selected && |
| 156 tab_strip->selected_index() != tab_index) { |
| 157 tab_strip->SelectTabContentsAt(tab_index, false); |
| 158 } |
54 | 159 |
55 return true; | 160 return true; |
56 } | 161 } |
57 | 162 |
58 | 163 |
| 164 bool RemoveTabFunction::RunImpl() { |
| 165 // TODO(rafaelw): This should have a callback, but it can't because it could |
| 166 // close it's own tab. |
| 167 |
| 168 if (!args_->IsType(Value::TYPE_INTEGER)) |
| 169 return false; |
| 170 |
| 171 Browser* browser = BrowserList::GetLastActive(); |
| 172 if (!browser) |
| 173 return false; |
| 174 |
| 175 int tab_id; |
| 176 if (!args_->GetAsInteger(&tab_id)) { |
| 177 return false; |
| 178 } |
| 179 |
| 180 int tab_index; |
| 181 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 182 if (GetIndexOfTabId(tab_strip, tab_id, &tab_index)) { |
| 183 TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
| 184 NavigationController* controller = tab_contents->controller(); |
| 185 DCHECK(controller); |
| 186 browser->CloseContents(tab_contents); |
| 187 return true; |
| 188 } |
| 189 |
| 190 return false; |
| 191 } |
| 192 |
59 // static helpers | 193 // static helpers |
60 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip, | 194 static DictionaryValue* CreateTabValue(TabStripModel* tab_strip, |
61 int tab_index) { | 195 int tab_index) { |
62 TabContents* contents = tab_strip->GetTabContentsAt(tab_index); | 196 TabContents* contents = tab_strip->GetTabContentsAt(tab_index); |
63 NavigationController* controller = contents->controller(); | 197 NavigationController* controller = contents->controller(); |
64 DCHECK(controller); // TODO(aa): Is this a valid assumption? | 198 DCHECK(controller); // TODO(aa): Is this a valid assumption? |
65 | 199 |
66 DictionaryValue* result = new DictionaryValue(); | 200 DictionaryValue* result = new DictionaryValue(); |
67 result->SetInteger(L"id", controller->session_id().id()); | 201 result->SetInteger(L"id", controller->session_id().id()); |
| 202 result->SetInteger(L"index", tab_index); |
68 result->SetInteger(L"windowId", controller->window_id().id()); | 203 result->SetInteger(L"windowId", controller->window_id().id()); |
69 result->SetString(L"url", contents->GetURL().spec()); | 204 result->SetString(L"url", contents->GetURL().spec()); |
70 result->SetString(L"title", UTF16ToWide(contents->GetTitle())); | 205 result->SetString(L"title", UTF16ToWide(contents->GetTitle())); |
71 result->SetBoolean(L"selected", tab_index == tab_strip->selected_index()); | 206 result->SetBoolean(L"selected", tab_index == tab_strip->selected_index()); |
72 | 207 |
73 NavigationEntry* entry = controller->GetActiveEntry(); | 208 NavigationEntry* entry = controller->GetActiveEntry(); |
74 if (entry) { | 209 if (entry) { |
75 if (entry->favicon().is_valid()) | 210 if (entry->favicon().is_valid()) |
76 result->SetString(L"favIconUrl", entry->favicon().url().spec()); | 211 result->SetString(L"favIconUrl", entry->favicon().url().spec()); |
77 } | 212 } |
78 | 213 |
79 return result; | 214 return result; |
80 } | 215 } |
| 216 |
| 217 static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, |
| 218 int* tab_index) { |
| 219 for (int i = 0; i < tab_strip->count(); ++i) { |
| 220 TabContents* tab_contents = tab_strip->GetTabContentsAt(i); |
| 221 NavigationController* controller = tab_contents->controller(); |
| 222 DCHECK(controller); // TODO(aa): Is this a valid assumption? |
| 223 |
| 224 if (controller->session_id().id() == tab_id) { |
| 225 *tab_index = i; |
| 226 return true; |
| 227 } |
| 228 } |
| 229 return false; |
| 230 } |
OLD | NEW |