OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_browser_event_router.h" | 5 #include "chrome/browser/extensions/extension_browser_event_router.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
10 #include "chrome/browser/profile.h" | 10 #include "chrome/browser/profile.h" |
11 #include "chrome/browser/extensions/extension_event_names.h" | 11 #include "chrome/browser/extensions/extension_event_names.h" |
12 #include "chrome/browser/extensions/extension_message_service.h" | 12 #include "chrome/browser/extensions/extension_message_service.h" |
13 #include "chrome/browser/extensions/extension_tabs_module_constants.h" | 13 #include "chrome/browser/extensions/extension_tabs_module_constants.h" |
14 #include "chrome/browser/extensions/extension_page_actions_module_constants.h" | 14 #include "chrome/browser/extensions/extension_page_actions_module_constants.h" |
15 #include "chrome/browser/tab_contents/navigation_entry.h" | 15 #include "chrome/browser/tab_contents/navigation_entry.h" |
16 #include "chrome/browser/tab_contents/tab_contents.h" | 16 #include "chrome/browser/tab_contents/tab_contents.h" |
17 #include "chrome/common/extensions/extension.h" | 17 #include "chrome/common/extensions/extension.h" |
18 #include "chrome/common/notification_service.h" | 18 #include "chrome/common/notification_service.h" |
19 | 19 |
20 namespace events = extension_event_names; | 20 namespace events = extension_event_names; |
21 namespace tab_keys = extension_tabs_module_constants; | 21 namespace tab_keys = extension_tabs_module_constants; |
22 namespace page_action_keys = extension_page_actions_module_constants; | 22 namespace page_action_keys = extension_page_actions_module_constants; |
23 | 23 |
24 ExtensionBrowserEventRouter::TabEntry::TabEntry() | 24 ExtensionBrowserEventRouter::TabEntry::TabEntry() |
25 : state_(ExtensionTabUtil::TAB_COMPLETE), | 25 : complete_waiting_on_load_(false), |
26 pending_navigate_(false), | |
27 url_() { | 26 url_() { |
28 } | 27 } |
29 | 28 |
30 ExtensionBrowserEventRouter::TabEntry::TabEntry(const TabContents* contents) | |
31 : state_(ExtensionTabUtil::TAB_COMPLETE), | |
32 pending_navigate_(false), | |
33 url_(contents->GetURL()) { | |
34 UpdateLoadState(contents); | |
35 } | |
36 | |
37 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::UpdateLoadState( | 29 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::UpdateLoadState( |
38 const TabContents* contents) { | 30 const TabContents* contents) { |
39 ExtensionTabUtil::TabStatus old_state = state_; | 31 // The tab may go in & out of loading (for instance if iframes navigate). |
40 state_ = ExtensionTabUtil::GetTabStatus(contents); | 32 // We only want to respond to the first change from loading to !loading after |
41 | 33 // the NAV_ENTRY_COMMITTED was fired. |
42 if (old_state == state_) | 34 if (!complete_waiting_on_load_ || contents->is_loading()) |
43 return false; | |
44 | |
45 if (state_ == ExtensionTabUtil::TAB_LOADING) { | |
46 // Do not send "loading" state changed now. Wait for navigate so the new | |
47 // url is available. | |
48 pending_navigate_ = true; | |
49 return NULL; | 35 return NULL; |
50 | 36 |
51 } else if (state_ == ExtensionTabUtil::TAB_COMPLETE) { | 37 // Send "complete" state change. |
52 // Send "complete" state change. | 38 complete_waiting_on_load_ = false; |
53 DictionaryValue* changed_properties = new DictionaryValue(); | 39 DictionaryValue* changed_properties = new DictionaryValue(); |
54 changed_properties->SetString(tab_keys::kStatusKey, | 40 changed_properties->SetString(tab_keys::kStatusKey, |
55 tab_keys::kStatusValueComplete); | 41 tab_keys::kStatusValueComplete); |
56 return changed_properties; | 42 return changed_properties; |
57 | |
58 } else { | |
59 NOTREACHED(); | |
60 return NULL; | |
61 } | |
62 } | 43 } |
63 | 44 |
64 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::DidNavigate( | 45 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::DidNavigate( |
65 const TabContents* contents) { | 46 const TabContents* contents) { |
66 if (!pending_navigate_) | 47 // Send "loading" state change. |
67 return NULL; | 48 complete_waiting_on_load_ = true; |
68 | |
69 DictionaryValue* changed_properties = new DictionaryValue(); | 49 DictionaryValue* changed_properties = new DictionaryValue(); |
70 changed_properties->SetString(tab_keys::kStatusKey, | 50 changed_properties->SetString(tab_keys::kStatusKey, |
71 tab_keys::kStatusValueLoading); | 51 tab_keys::kStatusValueLoading); |
72 | 52 |
73 GURL new_url = contents->GetURL(); | 53 if (contents->GetURL() != url_) { |
74 if (new_url != url_) { | 54 url_ = contents->GetURL(); |
75 url_ = new_url; | |
76 changed_properties->SetString(tab_keys::kUrlKey, url_.spec()); | 55 changed_properties->SetString(tab_keys::kUrlKey, url_.spec()); |
77 } | 56 } |
78 | 57 |
79 pending_navigate_ = false; | |
80 return changed_properties; | 58 return changed_properties; |
81 } | 59 } |
82 | 60 |
83 ExtensionBrowserEventRouter* ExtensionBrowserEventRouter::GetInstance() { | 61 ExtensionBrowserEventRouter* ExtensionBrowserEventRouter::GetInstance() { |
84 return Singleton<ExtensionBrowserEventRouter>::get(); | 62 return Singleton<ExtensionBrowserEventRouter>::get(); |
85 } | 63 } |
86 | 64 |
87 static void DispatchEvent(Profile* profile, | 65 static void DispatchEvent(Profile* profile, |
88 const char* event_name, | 66 const char* event_name, |
89 const std::string json_args) { | 67 const std::string json_args) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 for (BrowserList::const_iterator iter = BrowserList::begin(); | 104 for (BrowserList::const_iterator iter = BrowserList::begin(); |
127 iter != BrowserList::end(); ++iter) { | 105 iter != BrowserList::end(); ++iter) { |
128 RegisterForBrowserNotifications(*iter); | 106 RegisterForBrowserNotifications(*iter); |
129 | 107 |
130 // Also catch up our internal bookkeeping of tab entries. | 108 // Also catch up our internal bookkeeping of tab entries. |
131 Browser* browser = *iter; | 109 Browser* browser = *iter; |
132 if (browser->tabstrip_model()) { | 110 if (browser->tabstrip_model()) { |
133 for (int i = 0; i < browser->tabstrip_model()->count(); ++i) { | 111 for (int i = 0; i < browser->tabstrip_model()->count(); ++i) { |
134 TabContents* contents = browser->tabstrip_model()->GetTabContentsAt(i); | 112 TabContents* contents = browser->tabstrip_model()->GetTabContentsAt(i); |
135 int tab_id = ExtensionTabUtil::GetTabId(contents); | 113 int tab_id = ExtensionTabUtil::GetTabId(contents); |
136 tab_entries_[tab_id] = TabEntry(contents); | 114 tab_entries_[tab_id] = TabEntry(); |
137 } | 115 } |
138 } | 116 } |
139 } | 117 } |
140 | 118 |
141 initialized_ = true; | 119 initialized_ = true; |
142 } | 120 } |
143 | 121 |
144 ExtensionBrowserEventRouter::ExtensionBrowserEventRouter() | 122 ExtensionBrowserEventRouter::ExtensionBrowserEventRouter() |
145 : initialized_(false) { } | 123 : initialized_(false) { } |
146 | 124 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 196 |
219 RegisterForTabNotifications(contents); | 197 RegisterForTabNotifications(contents); |
220 } | 198 } |
221 | 199 |
222 void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents, | 200 void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents, |
223 int index, | 201 int index, |
224 bool foreground) { | 202 bool foreground) { |
225 // If tab is new, send created event. | 203 // If tab is new, send created event. |
226 int tab_id = ExtensionTabUtil::GetTabId(contents); | 204 int tab_id = ExtensionTabUtil::GetTabId(contents); |
227 if (tab_entries_.find(tab_id) == tab_entries_.end()) { | 205 if (tab_entries_.find(tab_id) == tab_entries_.end()) { |
228 tab_entries_[tab_id] = TabEntry(contents); | 206 tab_entries_[tab_id] = TabEntry(); |
229 | 207 |
230 TabCreatedAt(contents, index, foreground); | 208 TabCreatedAt(contents, index, foreground); |
231 return; | 209 return; |
232 } | 210 } |
233 | 211 |
234 ListValue args; | 212 ListValue args; |
235 args.Append(Value::CreateIntegerValue(tab_id)); | 213 args.Append(Value::CreateIntegerValue(tab_id)); |
236 | 214 |
237 DictionaryValue* object_args = new DictionaryValue(); | 215 DictionaryValue* object_args = new DictionaryValue(); |
238 object_args->Set(tab_keys::kNewWindowIdKey, Value::CreateIntegerValue( | 216 object_args->Set(tab_keys::kNewWindowIdKey, Value::CreateIntegerValue( |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 | 425 |
448 void ExtensionBrowserEventRouter::BrowserActionExecuted( | 426 void ExtensionBrowserEventRouter::BrowserActionExecuted( |
449 Profile* profile, const std::string& extension_id, Browser* browser) { | 427 Profile* profile, const std::string& extension_id, Browser* browser) { |
450 TabContents* tab_contents = NULL; | 428 TabContents* tab_contents = NULL; |
451 int tab_id = 0; | 429 int tab_id = 0; |
452 if (!ExtensionTabUtil::GetDefaultTab(browser, &tab_contents, &tab_id)) | 430 if (!ExtensionTabUtil::GetDefaultTab(browser, &tab_contents, &tab_id)) |
453 return; | 431 return; |
454 std::string event_name = std::string("browserAction/") + extension_id; | 432 std::string event_name = std::string("browserAction/") + extension_id; |
455 DispatchEventWithTab(profile, event_name.c_str(), tab_contents); | 433 DispatchEventWithTab(profile, event_name.c_str(), tab_contents); |
456 } | 434 } |
OLD | NEW |