Index: chrome/browser/extensions/extension_tabs_module.cc |
=================================================================== |
--- chrome/browser/extensions/extension_tabs_module.cc (revision 13446) |
+++ chrome/browser/extensions/extension_tabs_module.cc (working copy) |
@@ -14,6 +14,9 @@ |
static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model, |
int tab_index); |
+static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, |
+ int* tab_index); |
+ |
bool GetTabsForWindowFunction::RunImpl() { |
if (!args_->IsType(Value::TYPE_NULL)) |
return false; |
@@ -41,21 +44,152 @@ |
if (!browser) |
return false; |
- // TODO(aa): Handle all the other properties of the new tab. |
+ TabStripModel *tab_strip = browser->tabstrip_model(); |
+ const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); |
+ |
+ // TODO(rafaelw): handle setting remaining tab properties: |
+ // -windowId |
+ // -title |
+ // -favIconUrl |
+ |
std::string url; |
- static_cast<const DictionaryValue*>(args_)->GetString(L"url", &url); |
- browser->AddTabWithURL(GURL(url), GURL(), PageTransition::TYPED, true, -1, |
- NULL); |
+ args_hash->GetString(L"url", &url); |
+ // Default to foreground for the new tab. The presence of 'selected' property |
+ // will override this default. |
+ bool selected = true; |
+ args_hash->GetBoolean(L"selected", &selected); |
+ |
+ // If index is specified, honor the value, but keep it bound to |
+ // 0 <= index <= tab_strip->count() |
+ int index = -1; |
+ args_hash->GetInteger(L"index", &index); |
+ if (index < 0) { |
+ // Default insert behavior |
+ index = -1; |
+ } |
+ if (index > tab_strip->count()) { |
+ index = tab_strip->count(); |
+ } |
+ |
+ TabContents* contents = browser->AddTabWithURL(GURL(url), GURL(), |
+ PageTransition::TYPED, selected, index, NULL); |
+ index = tab_strip->GetIndexOfTabContents(contents); |
+ |
// Return data about the newly created tab. |
if (has_callback()) |
- result_.reset(CreateTabValue(browser->tabstrip_model(), |
- browser->tabstrip_model()->count() - 1)); |
+ result_.reset(CreateTabValue(tab_strip, index)); |
return true; |
} |
+bool GetTabFunction::RunImpl() { |
+ if (!args_->IsType(Value::TYPE_INTEGER)) |
+ return false; |
+ Browser* browser = BrowserList::GetLastActive(); |
+ if (!browser) |
+ return false; |
+ |
+ int tab_id; |
+ args_->GetAsInteger(&tab_id); |
+ |
+ int tab_index; |
+ TabStripModel* tab_strip = browser->tabstrip_model(); |
+ // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
+ if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
+ return false; |
+ |
+ TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
+ NavigationController* controller = tab_contents->controller(); |
+ DCHECK(controller); |
+ result_.reset(CreateTabValue(tab_strip, tab_index)); |
+ return true; |
+} |
+ |
+bool UpdateTabFunction::RunImpl() { |
+ // TODO(aa): Do data-driven validation in JS. |
+ if (!args_->IsType(Value::TYPE_DICTIONARY)) |
+ return false; |
+ |
+ Browser* browser = BrowserList::GetLastActive(); |
+ if (!browser) |
+ return false; |
+ |
+ int tab_id; |
+ const DictionaryValue *args_hash = static_cast<const DictionaryValue*>(args_); |
+ if (!args_hash->GetInteger(L"id", &tab_id)) |
+ return false; |
+ |
+ int tab_index; |
+ TabStripModel* tab_strip = browser->tabstrip_model(); |
+ // TODO(rafaelw): return an error if the tab is not found by |tab_id| |
+ if (!GetIndexOfTabId(tab_strip, tab_id, &tab_index)) |
+ return false; |
+ |
+ TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
+ NavigationController* controller = tab_contents->controller(); |
+ DCHECK(controller); |
+ |
+ // TODO(rafaelw): handle setting remaining tab properties: |
+ // -index |
+ // -windowId |
+ // -title |
+ // -favIconUrl |
+ |
+ // Navigate the tab to a new location if the url different. |
+ std::string url; |
+ if (args_hash->GetString(L"url", &url)) { |
+ GURL new_gurl(url); |
+ if (new_gurl.is_valid()) { |
+ controller->LoadURL(new_gurl, GURL(), PageTransition::TYPED); |
+ } else { |
+ // TODO(rafaelw): return some reasonable error? |
+ } |
+ } |
+ |
+ bool selected; |
+ // TODO(rafaelw): Setting |selected| from js doesn't make much sense. |
+ // Move tab selection management up to window. |
+ if (args_hash->GetBoolean(L"selected", &selected) && |
+ selected && |
+ tab_strip->selected_index() != tab_index) { |
+ tab_strip->SelectTabContentsAt(tab_index, false); |
+ } |
+ |
+ return true; |
+} |
+ |
+ |
+bool RemoveTabFunction::RunImpl() { |
+ // TODO(rafaelw): This should have a callback, but it can't because it could |
+ // close it's own tab. |
+ |
+ if (!args_->IsType(Value::TYPE_INTEGER)) |
+ return false; |
+ |
+ Browser* browser = BrowserList::GetLastActive(); |
+ if (!browser) |
+ return false; |
+ |
+ int tab_id; |
+ if (!args_->GetAsInteger(&tab_id)) { |
+ return false; |
+ } |
+ |
+ int tab_index; |
+ TabStripModel* tab_strip = browser->tabstrip_model(); |
+ if (GetIndexOfTabId(tab_strip, tab_id, &tab_index)) { |
+ TabContents* tab_contents = tab_strip->GetTabContentsAt(tab_index); |
+ NavigationController* controller = tab_contents->controller(); |
+ DCHECK(controller); |
+ browser->CloseContents(tab_contents); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
// static helpers |
static DictionaryValue* CreateTabValue(TabStripModel* tab_strip, |
int tab_index) { |
@@ -65,6 +199,7 @@ |
DictionaryValue* result = new DictionaryValue(); |
result->SetInteger(L"id", controller->session_id().id()); |
+ result->SetInteger(L"index", tab_index); |
result->SetInteger(L"windowId", controller->window_id().id()); |
result->SetString(L"url", contents->GetURL().spec()); |
result->SetString(L"title", UTF16ToWide(contents->GetTitle())); |
@@ -78,3 +213,18 @@ |
return result; |
} |
+ |
+static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id, |
+ int* tab_index) { |
+ for (int i = 0; i < tab_strip->count(); ++i) { |
+ TabContents* tab_contents = tab_strip->GetTabContentsAt(i); |
+ NavigationController* controller = tab_contents->controller(); |
+ DCHECK(controller); // TODO(aa): Is this a valid assumption? |
+ |
+ if (controller->session_id().id() == tab_id) { |
+ *tab_index = i; |
+ return true; |
+ } |
+ } |
+ return false; |
+} |