summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-15 04:25:34 +0000
committerrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-15 04:25:34 +0000
commite9a4513ccdb40e341a699285d174b60f20736966 (patch)
tree7b2ea16fcc25f9b3d6524563e7f92b2907117d93 /chrome/browser
parent5d063840bdb2c53dc013e2bad48d76cb43ac89a5 (diff)
downloadchromium_src-e9a4513ccdb40e341a699285d174b60f20736966.zip
chromium_src-e9a4513ccdb40e341a699285d174b60f20736966.tar.gz
chromium_src-e9a4513ccdb40e341a699285d174b60f20736966.tar.bz2
Uploaded & applied on behalf of Roger Tawa (rogerta@google.com).
BUG=11200 R=aa,rafaelw http://codereview.chromium.org/115250 Review URL: http://codereview.chromium.org/113442 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16146 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc57
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h37
-rw-r--r--chrome/browser/extensions/extension_tabs_module.cc49
-rw-r--r--chrome/browser/extensions/extension_tabs_module.h13
4 files changed, 136 insertions, 20 deletions
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
index f4853ea..869b02c 100644
--- a/chrome/browser/extensions/extension_browser_event_router.cc
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -10,11 +10,11 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/extensions/extension.h"
#include "chrome/browser/extensions/extension_message_service.h"
-#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/common/notification_service.h"
const char* kOnPageActionExecuted = "page-action-executed";
const char* kOnTabCreated = "tab-created";
+const char* kOnTabUpdated = "tab-updated";
const char* kOnTabMoved = "tab-moved";
const char* kOnTabSelectionChanged = "tab-selection-changed";
const char* kOnTabAttached = "tab-attached";
@@ -24,6 +24,22 @@ const char* kOnWindowCreated = "window-created";
const char* kOnWindowRemoved = "window-removed";
const char* kOnWindowFocusedChanged = "window-focus-changed";
+ExtensionBrowserEventRouter::TabEntry::TabEntry()
+ : state_(ExtensionTabUtil::TAB_COMPLETE) {
+}
+
+ExtensionBrowserEventRouter::TabEntry::TabEntry(const TabContents* contents)
+ : state_(ExtensionTabUtil::TAB_COMPLETE) {
+ UpdateState(contents);
+}
+
+bool ExtensionBrowserEventRouter::TabEntry::UpdateState(
+ const TabContents* contents) {
+ ExtensionTabUtil::TabStatus old_state = state_;
+ state_ = ExtensionTabUtil::GetTabStatus(contents);
+ return old_state != state_;
+}
+
ExtensionBrowserEventRouter* ExtensionBrowserEventRouter::GetInstance() {
return Singleton<ExtensionBrowserEventRouter>::get();
}
@@ -61,7 +77,7 @@ ExtensionBrowserEventRouter::ExtensionBrowserEventRouter()
void ExtensionBrowserEventRouter::OnBrowserAdded(const Browser* browser) {
// Start listening to TabStripModel events for this browser.
browser->tabstrip_model()->AddObserver(this);
-
+
DispatchSimpleBrowserEvent(browser->profile(),
ExtensionTabUtil::GetWindowId(browser),
kOnWindowCreated);
@@ -99,8 +115,8 @@ void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
bool foreground) {
// If tab is new, send tab-created event.
int tab_id = ExtensionTabUtil::GetTabId(contents);
- if (tab_ids_.find(tab_id) == tab_ids_.end()) {
- tab_ids_.insert(tab_id);
+ if (tab_entries_.find(tab_id) == tab_entries_.end()) {
+ tab_entries_[tab_id] = TabEntry(contents);
TabCreatedAt(contents, index, foreground);
return;
@@ -108,7 +124,7 @@ void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
ListValue args;
args.Append(Value::CreateIntegerValue(tab_id));
-
+
DictionaryValue *object_args = new DictionaryValue();
object_args->Set(L"newWindowId", Value::CreateIntegerValue(
ExtensionTabUtil::GetWindowIdOfTab(contents)));
@@ -124,14 +140,14 @@ void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
void ExtensionBrowserEventRouter::TabDetachedAt(TabContents* contents,
int index) {
int tab_id = ExtensionTabUtil::GetTabId(contents);
- if (tab_ids_.find(tab_id) == tab_ids_.end()) {
+ if (tab_entries_.find(tab_id) == tab_entries_.end()) {
// The tab was removed. Don't send detach event.
return;
}
ListValue args;
args.Append(Value::CreateIntegerValue(tab_id));
-
+
DictionaryValue *object_args = new DictionaryValue();
object_args->Set(L"oldWindowId", Value::CreateIntegerValue(
ExtensionTabUtil::GetWindowIdOfTab(contents)));
@@ -156,7 +172,7 @@ void ExtensionBrowserEventRouter::TabClosingAt(TabContents* contents,
DispatchEvent(contents->profile(), kOnTabRemoved, json_args);
- int removed_count = tab_ids_.erase(tab_id);
+ int removed_count = tab_entries_.erase(tab_id);
DCHECK(removed_count > 0);
}
@@ -167,7 +183,7 @@ void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents,
ListValue args;
args.Append(Value::CreateIntegerValue(
ExtensionTabUtil::GetTabId(new_contents)));
-
+
DictionaryValue *object_args = new DictionaryValue();
object_args->Set(L"windowId", Value::CreateIntegerValue(
ExtensionTabUtil::GetWindowIdOfTab(new_contents)));
@@ -184,7 +200,7 @@ void ExtensionBrowserEventRouter::TabMoved(TabContents* contents,
int to_index) {
ListValue args;
args.Append(Value::CreateIntegerValue(ExtensionTabUtil::GetTabId(contents)));
-
+
DictionaryValue *object_args = new DictionaryValue();
object_args->Set(L"windowId", Value::CreateIntegerValue(
ExtensionTabUtil::GetWindowIdOfTab(contents)));
@@ -200,7 +216,26 @@ void ExtensionBrowserEventRouter::TabMoved(TabContents* contents,
void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents,
int index,
- bool loading_only) { }
+ bool loading_only) {
+ int tab_id = ExtensionTabUtil::GetTabId(contents);
+ std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id);
+ if (tab_entries_.end() == i)
+ return;
+
+ TabEntry& entry = i->second;
+ if (entry.UpdateState(contents)) {
+ // The state of the tab (as seen from the extension point of view) has
+ // changed. Send a notification to the extension.
+ ListValue args;
+ args.Append(Value::CreateIntegerValue(tab_id));
+ args.Append(ExtensionTabUtil::CreateTabChangedValue(contents));
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+
+ DispatchEvent(contents->profile(), kOnTabUpdated, json_args);
+ }
+}
void ExtensionBrowserEventRouter::TabStripEmpty() { }
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
index afebdd3..749c6e3 100644
--- a/chrome/browser/extensions/extension_browser_event_router.h
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -5,13 +5,14 @@
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
+#include <map>
#include <vector>
-#include <set>
#include <string>
#include "base/basictypes.h"
#include "base/singleton.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_observer.h"
@@ -64,9 +65,37 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver,
bool initialized_;
- // Maintain set of known tab ids, so we can distinguish between tab creation
- // and tab insertion. Also used to not send tab-detached after tab-removed.
- std::set<int> tab_ids_;
+ // Maintain some information about known tabs, so we can:
+ //
+ // - distinguish between tab creation and tab insertion
+ // - not send tab-detached after tab-removed
+ // - reduce the "noise" of TabChangedAt() when sending events to extensions
+ class TabEntry {
+ public:
+ // Create a new tab entry whose initial state is TAB_COMPLETE. This
+ // constructor is required because TabEntry objects placed inside an
+ // std::map<> by value.
+ TabEntry();
+
+ // Create a new tab entry whose initial state is derived from the given
+ // tab contents.
+ explicit TabEntry(const TabContents* contents);
+
+ // Returns the current state of the tab.
+ ExtensionTabUtil::TabStatus state() const { return state_; }
+
+ // Update the state of the tab based on its TabContents. Returns true if
+ // the state changed, false otherwise. Whether the state has changed or not
+ // is used to determine if events needs to be sent to extensions during
+ // processing of TabChangedAt().
+ bool UpdateState(const TabContents* contents);
+
+ private:
+ // Tab state used for last notification to extensions.
+ ExtensionTabUtil::TabStatus state_;
+ };
+
+ std::map<int, TabEntry> tab_entries_;
DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserEventRouter);
};
diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc
index 6752449..073f54d 100644
--- a/chrome/browser/extensions/extension_tabs_module.cc
+++ b/chrome/browser/extensions/extension_tabs_module.cc
@@ -28,6 +28,7 @@ const wchar_t* kIndexKey = L"index";
const wchar_t* kWindowIdKey = L"windowId";
const wchar_t* kUrlKey = L"url";
const wchar_t* kTitleKey = L"title";
+const wchar_t* kStatusKey = L"status";
const wchar_t* kSelectedKey = L"selected";
const wchar_t* kFocusedKey = L"focused";
const wchar_t* kFavIconUrlKey = L"favIconUrl";
@@ -37,6 +38,10 @@ const wchar_t* kWidthKey = L"width";
const wchar_t* kHeightKey = L"height";
const wchar_t* kTabsKey = L"tabs";
+// Tab status text
+const char* kStatusValueLoading = "loading";
+const char* kStatusValueComplete = "complete";
+
// Error messages.
const char* kWindowNotFoundError = "No window with id: *.";
const char* kTabNotFoundError = "No tab with id: *.";
@@ -73,6 +78,25 @@ int ExtensionTabUtil::GetTabId(const TabContents* tab_contents) {
return tab_contents->controller().session_id().id();
}
+ExtensionTabUtil::TabStatus ExtensionTabUtil::GetTabStatus(
+ const TabContents* tab_contents) {
+ return tab_contents->is_loading() ? TAB_LOADING : TAB_COMPLETE;
+}
+
+std::string ExtensionTabUtil::GetTabStatusText(TabStatus status) {
+ std::string text;
+ switch (status) {
+ case TAB_LOADING:
+ text = kStatusValueLoading;
+ break;
+ case TAB_COMPLETE:
+ text = kStatusValueComplete;
+ break;
+ }
+
+ return text;
+}
+
int ExtensionTabUtil::GetWindowIdOfTab(const TabContents* tab_contents) {
return tab_contents->controller().window_id().id();
}
@@ -93,22 +117,37 @@ DictionaryValue* ExtensionTabUtil::CreateTabValue(
return ExtensionTabUtil::CreateTabValue(contents, NULL, -1);
}
+DictionaryValue* ExtensionTabUtil::CreateTabChangedValue(
+ const TabContents* contents) {
+ // A tab changed event should include a tab value that contains only the
+ // changed properties. For now, this means only the status property.
+ DictionaryValue* result = new DictionaryValue();
+ result->SetString(kStatusKey, GetTabStatusText(GetTabStatus(contents)));
+ return result;
+}
+
DictionaryValue* ExtensionTabUtil::CreateTabValue(
const TabContents* contents, TabStripModel* tab_strip, int tab_index) {
+ TabStatus status = GetTabStatus(contents);
+
DictionaryValue* result = new DictionaryValue();
result->SetInteger(kIdKey, ExtensionTabUtil::GetTabId(contents));
result->SetInteger(kIndexKey, tab_index);
result->SetInteger(kWindowIdKey,
ExtensionTabUtil::GetWindowIdOfTab(contents));
result->SetString(kUrlKey, contents->GetURL().spec());
- result->SetString(kTitleKey, UTF16ToWide(contents->GetTitle()));
+ result->SetString(kStatusKey, GetTabStatusText(status));
result->SetBoolean(kSelectedKey,
tab_strip && tab_index == tab_strip->selected_index());
- NavigationEntry* entry = contents->controller().GetActiveEntry();
- if (entry) {
- if (entry->favicon().is_valid())
- result->SetString(kFavIconUrlKey, entry->favicon().url().spec());
+ if (status != TAB_LOADING) {
+ result->SetString(kTitleKey, UTF16ToWide(contents->GetTitle()));
+
+ NavigationEntry* entry = contents->controller().GetActiveEntry();
+ if (entry) {
+ if (entry->favicon().is_valid())
+ result->SetString(kFavIconUrlKey, entry->favicon().url().spec());
+ }
}
return result;
diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h
index 8a004185..2dd2c27 100644
--- a/chrome/browser/extensions/extension_tabs_module.h
+++ b/chrome/browser/extensions/extension_tabs_module.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_TABS_MODULE_H__
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TABS_MODULE_H__
+#include <string>
+
#include "chrome/browser/extensions/extension_function.h"
class Browser;
@@ -14,13 +16,24 @@ class TabStripModel;
class ExtensionTabUtil {
public:
+ // Possible tab states. These states are used to calculate the "status"
+ // property of the Tab object that is used in the extension tab API.
+ enum TabStatus {
+ TAB_LOADING, // Waiting for the DOM to load.
+ TAB_COMPLETE // Tab loading and rendering is complete.
+ };
+
static int GetWindowId(const Browser* browser);
static int GetTabId(const TabContents* tab_contents);
+ static TabStatus GetTabStatus(const TabContents* tab_contents);
+ static std::string GetTabStatusText(TabStatus status);
static int GetWindowIdOfTab(const TabContents* tab_contents);
static DictionaryValue* CreateTabValue(const TabContents* tab_contents);
static DictionaryValue* CreateTabValue(const TabContents* tab_contents,
TabStripModel* tab_strip,
int tab_index);
+ static DictionaryValue* CreateTabChangedValue(const TabContents* contents);
+
// Any out parameter (|browser|, |tab_strip|, |contents|, & |tab_index|) may
// be NULL and will not be set within the function.
static bool GetTabById(int tab_id, Profile* profile, Browser** browser,