OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer/extensions/event_bindings.h" | 5 #include "chrome/renderer/extensions/event_bindings.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
14 #include "chrome/common/extensions/extension_messages.h" | 14 #include "chrome/common/extensions/extension_messages.h" |
15 #include "chrome/common/extensions/extension_set.h" | 15 #include "chrome/common/extensions/extension_set.h" |
16 #include "chrome/common/extensions/event_filter.h" | 16 #include "chrome/common/extensions/event_filter.h" |
17 #include "chrome/common/extensions/value_counter.h" | 17 #include "chrome/common/extensions/value_counter.h" |
18 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
19 #include "chrome/common/view_type.h" | 19 #include "chrome/common/view_type.h" |
20 #include "chrome/renderer/extensions/chrome_v8_context.h" | 20 #include "chrome/renderer/extensions/chrome_v8_context.h" |
21 #include "chrome/renderer/extensions/chrome_v8_context_set.h" | 21 #include "chrome/renderer/extensions/chrome_v8_context_set.h" |
22 #include "chrome/renderer/extensions/chrome_v8_extension.h" | 22 #include "chrome/renderer/extensions/chrome_v8_extension.h" |
| 23 #include "chrome/renderer/extensions/dispatcher.h" |
23 #include "chrome/renderer/extensions/event_bindings.h" | 24 #include "chrome/renderer/extensions/event_bindings.h" |
24 #include "chrome/renderer/extensions/extension_dispatcher.h" | |
25 #include "chrome/renderer/extensions/extension_helper.h" | 25 #include "chrome/renderer/extensions/extension_helper.h" |
26 #include "chrome/renderer/extensions/user_script_slave.h" | 26 #include "chrome/renderer/extensions/user_script_slave.h" |
27 #include "content/public/renderer/render_thread.h" | 27 #include "content/public/renderer/render_thread.h" |
28 #include "content/public/renderer/v8_value_converter.h" | 28 #include "content/public/renderer/v8_value_converter.h" |
29 #include "googleurl/src/gurl.h" | 29 #include "googleurl/src/gurl.h" |
30 #include "grit/renderer_resources.h" | 30 #include "grit/renderer_resources.h" |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
34 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" |
35 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLReques
t.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLReques
t.h" |
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
37 #include "v8/include/v8.h" | 37 #include "v8/include/v8.h" |
38 | 38 |
39 using WebKit::WebFrame; | 39 using WebKit::WebFrame; |
40 using WebKit::WebSecurityOrigin; | 40 using WebKit::WebSecurityOrigin; |
41 using WebKit::WebURL; | 41 using WebKit::WebURL; |
42 using content::RenderThread; | 42 using content::RenderThread; |
43 using extensions::Extension; | 43 using extensions::Extension; |
44 | 44 |
| 45 namespace extensions { |
| 46 |
45 namespace { | 47 namespace { |
46 | 48 |
47 // A map of event names to the number of contexts listening to that event. | 49 // A map of event names to the number of contexts listening to that event. |
48 // We notify the browser about event listeners when we transition between 0 | 50 // We notify the browser about event listeners when we transition between 0 |
49 // and 1. | 51 // and 1. |
50 typedef std::map<std::string, int> EventListenerCounts; | 52 typedef std::map<std::string, int> EventListenerCounts; |
51 | 53 |
52 // A map of extension IDs to listener counts for that extension. | 54 // A map of extension IDs to listener counts for that extension. |
53 base::LazyInstance<std::map<std::string, EventListenerCounts> > | 55 base::LazyInstance<std::map<std::string, EventListenerCounts> > |
54 g_listener_counts = LAZY_INSTANCE_INITIALIZER; | 56 g_listener_counts = LAZY_INSTANCE_INITIALIZER; |
55 | 57 |
56 // A map of event names to a (filter -> count) map. The map is used to keep | 58 // A map of event names to a (filter -> count) map. The map is used to keep |
57 // track of which filters are in effect for which events. | 59 // track of which filters are in effect for which events. |
58 // We notify the browser about filtered event listeners when we transition | 60 // We notify the browser about filtered event listeners when we transition |
59 // between 0 and 1. | 61 // between 0 and 1. |
60 typedef std::map<std::string, linked_ptr<extensions::ValueCounter> > | 62 typedef std::map<std::string, linked_ptr<extensions::ValueCounter> > |
61 FilteredEventListenerCounts; | 63 FilteredEventListenerCounts; |
62 | 64 |
63 // A map of extension IDs to filtered listener counts for that extension. | 65 // A map of extension IDs to filtered listener counts for that extension. |
64 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > | 66 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > |
65 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; | 67 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; |
66 | 68 |
67 base::LazyInstance<extensions::EventFilter> g_event_filter = | 69 base::LazyInstance<extensions::EventFilter> g_event_filter = |
68 LAZY_INSTANCE_INITIALIZER; | 70 LAZY_INSTANCE_INITIALIZER; |
69 | 71 |
70 // TODO(koz): Merge this into EventBindings. | 72 // TODO(koz): Merge this into EventBindings. |
71 class ExtensionImpl : public ChromeV8Extension { | 73 class ExtensionImpl : public ChromeV8Extension { |
72 public: | 74 public: |
73 | 75 |
74 explicit ExtensionImpl(ExtensionDispatcher* dispatcher) | 76 explicit ExtensionImpl(Dispatcher* dispatcher) |
75 : ChromeV8Extension(dispatcher) { | 77 : ChromeV8Extension(dispatcher) { |
76 RouteStaticFunction("AttachEvent", &AttachEvent); | 78 RouteStaticFunction("AttachEvent", &AttachEvent); |
77 RouteStaticFunction("DetachEvent", &DetachEvent); | 79 RouteStaticFunction("DetachEvent", &DetachEvent); |
78 RouteStaticFunction("AttachFilteredEvent", &AttachFilteredEvent); | 80 RouteStaticFunction("AttachFilteredEvent", &AttachFilteredEvent); |
79 RouteStaticFunction("DetachFilteredEvent", &DetachFilteredEvent); | 81 RouteStaticFunction("DetachFilteredEvent", &DetachFilteredEvent); |
80 RouteStaticFunction("MatchAgainstEventFilter", &MatchAgainstEventFilter); | 82 RouteStaticFunction("MatchAgainstEventFilter", &MatchAgainstEventFilter); |
81 } | 83 } |
82 | 84 |
83 ~ExtensionImpl() {} | 85 ~ExtensionImpl() {} |
84 | 86 |
85 // Attach an event name to an object. | 87 // Attach an event name to an object. |
86 static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { | 88 static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { |
87 DCHECK(args.Length() == 1); | 89 DCHECK(args.Length() == 1); |
88 // TODO(erikkay) should enforce that event name is a string in the bindings | 90 // TODO(erikkay) should enforce that event name is a string in the bindings |
89 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); | 91 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); |
90 | 92 |
91 if (args[0]->IsString()) { | 93 if (args[0]->IsString()) { |
92 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); | 94 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); |
93 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); | 95 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); |
94 ExtensionDispatcher* extension_dispatcher = self->extension_dispatcher(); | 96 Dispatcher* dispatcher = self->dispatcher(); |
95 const ChromeV8ContextSet& context_set = | 97 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); |
96 extension_dispatcher->v8_context_set(); | |
97 ChromeV8Context* context = context_set.GetCurrent(); | 98 ChromeV8Context* context = context_set.GetCurrent(); |
98 CHECK(context); | 99 CHECK(context); |
99 | 100 |
100 if (!extension_dispatcher->CheckCurrentContextAccessToExtensionAPI( | 101 if (!dispatcher->CheckCurrentContextAccessToExtensionAPI(event_name)) |
101 event_name)) | |
102 return v8::Undefined(); | 102 return v8::Undefined(); |
103 | 103 |
104 std::string extension_id = context->GetExtensionID(); | 104 std::string extension_id = context->GetExtensionID(); |
105 EventListenerCounts& listener_counts = | 105 EventListenerCounts& listener_counts = |
106 g_listener_counts.Get()[extension_id]; | 106 g_listener_counts.Get()[extension_id]; |
107 if (++listener_counts[event_name] == 1) { | 107 if (++listener_counts[event_name] == 1) { |
108 content::RenderThread::Get()->Send( | 108 content::RenderThread::Get()->Send( |
109 new ExtensionHostMsg_AddListener(extension_id, event_name)); | 109 new ExtensionHostMsg_AddListener(extension_id, event_name)); |
110 } | 110 } |
111 | 111 |
(...skipping 11 matching lines...) Expand all Loading... |
123 static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { | 123 static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { |
124 DCHECK(args.Length() == 2); | 124 DCHECK(args.Length() == 2); |
125 // TODO(erikkay) should enforce that event name is a string in the bindings | 125 // TODO(erikkay) should enforce that event name is a string in the bindings |
126 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); | 126 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); |
127 | 127 |
128 if (args[0]->IsString() && args[1]->IsBoolean()) { | 128 if (args[0]->IsString() && args[1]->IsBoolean()) { |
129 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); | 129 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); |
130 bool is_manual = args[1]->BooleanValue(); | 130 bool is_manual = args[1]->BooleanValue(); |
131 | 131 |
132 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); | 132 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); |
133 ExtensionDispatcher* extension_dispatcher = self->extension_dispatcher(); | 133 Dispatcher* dispatcher = self->dispatcher(); |
134 const ChromeV8ContextSet& context_set = | 134 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); |
135 extension_dispatcher->v8_context_set(); | |
136 ChromeV8Context* context = context_set.GetCurrent(); | 135 ChromeV8Context* context = context_set.GetCurrent(); |
137 if (!context) | 136 if (!context) |
138 return v8::Undefined(); | 137 return v8::Undefined(); |
139 | 138 |
140 std::string extension_id = context->GetExtensionID(); | 139 std::string extension_id = context->GetExtensionID(); |
141 EventListenerCounts& listener_counts = | 140 EventListenerCounts& listener_counts = |
142 g_listener_counts.Get()[extension_id]; | 141 g_listener_counts.Get()[extension_id]; |
143 | 142 |
144 if (--listener_counts[event_name] == 0) { | 143 if (--listener_counts[event_name] == 0) { |
145 content::RenderThread::Get()->Send( | 144 content::RenderThread::Get()->Send( |
(...skipping 16 matching lines...) Expand all Loading... |
162 // event_name - Name of the event to attach. | 161 // event_name - Name of the event to attach. |
163 // filter - Which instances of the named event are we interested in. | 162 // filter - Which instances of the named event are we interested in. |
164 // returns the id assigned to the listener, which will be returned from calls | 163 // returns the id assigned to the listener, which will be returned from calls |
165 // to MatchAgainstEventFilter where this listener matches. | 164 // to MatchAgainstEventFilter where this listener matches. |
166 static v8::Handle<v8::Value> AttachFilteredEvent(const v8::Arguments& args) { | 165 static v8::Handle<v8::Value> AttachFilteredEvent(const v8::Arguments& args) { |
167 DCHECK_EQ(2, args.Length()); | 166 DCHECK_EQ(2, args.Length()); |
168 DCHECK(args[0]->IsString()); | 167 DCHECK(args[0]->IsString()); |
169 DCHECK(args[1]->IsObject()); | 168 DCHECK(args[1]->IsObject()); |
170 | 169 |
171 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); | 170 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); |
172 ExtensionDispatcher* extension_dispatcher = self->extension_dispatcher(); | 171 Dispatcher* dispatcher = self->dispatcher(); |
173 const ChromeV8ContextSet& context_set = | 172 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); |
174 extension_dispatcher->v8_context_set(); | |
175 ChromeV8Context* context = context_set.GetCurrent(); | 173 ChromeV8Context* context = context_set.GetCurrent(); |
176 DCHECK(context); | 174 DCHECK(context); |
177 if (!context) | 175 if (!context) |
178 return v8::Integer::New(-1); | 176 return v8::Integer::New(-1); |
179 | 177 |
180 std::string event_name = *v8::String::AsciiValue(args[0]); | 178 std::string event_name = *v8::String::AsciiValue(args[0]); |
181 // This method throws an exception if it returns false. | 179 // This method throws an exception if it returns false. |
182 if (!extension_dispatcher->CheckCurrentContextAccessToExtensionAPI( | 180 if (!dispatcher->CheckCurrentContextAccessToExtensionAPI(event_name)) |
183 event_name)) | |
184 return v8::Undefined(); | 181 return v8::Undefined(); |
185 | 182 |
186 std::string extension_id = context->GetExtensionID(); | 183 std::string extension_id = context->GetExtensionID(); |
187 if (extension_id.empty()) | 184 if (extension_id.empty()) |
188 return v8::Integer::New(-1); | 185 return v8::Integer::New(-1); |
189 | 186 |
190 scoped_ptr<base::DictionaryValue> filter; | 187 scoped_ptr<base::DictionaryValue> filter; |
191 scoped_ptr<content::V8ValueConverter> converter( | 188 scoped_ptr<content::V8ValueConverter> converter( |
192 content::V8ValueConverter::create()); | 189 content::V8ValueConverter::create()); |
193 | 190 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // void DetachFilteredEvent(int id, bool manual) | 243 // void DetachFilteredEvent(int id, bool manual) |
247 // id - Id of the event to detach. | 244 // id - Id of the event to detach. |
248 // manual - false if this is part of the extension unload process where all | 245 // manual - false if this is part of the extension unload process where all |
249 // listeners are automatically detached. | 246 // listeners are automatically detached. |
250 static v8::Handle<v8::Value> DetachFilteredEvent(const v8::Arguments& args) { | 247 static v8::Handle<v8::Value> DetachFilteredEvent(const v8::Arguments& args) { |
251 DCHECK_EQ(2, args.Length()); | 248 DCHECK_EQ(2, args.Length()); |
252 DCHECK(args[0]->IsInt32()); | 249 DCHECK(args[0]->IsInt32()); |
253 DCHECK(args[1]->IsBoolean()); | 250 DCHECK(args[1]->IsBoolean()); |
254 bool is_manual = args[1]->BooleanValue(); | 251 bool is_manual = args[1]->BooleanValue(); |
255 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); | 252 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); |
256 ExtensionDispatcher* extension_dispatcher = self->extension_dispatcher(); | 253 Dispatcher* dispatcher = self->dispatcher(); |
257 const ChromeV8ContextSet& context_set = | 254 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); |
258 extension_dispatcher->v8_context_set(); | |
259 ChromeV8Context* context = context_set.GetCurrent(); | 255 ChromeV8Context* context = context_set.GetCurrent(); |
260 if (!context) | 256 if (!context) |
261 return v8::Undefined(); | 257 return v8::Undefined(); |
262 | 258 |
263 std::string extension_id = context->GetExtensionID(); | 259 std::string extension_id = context->GetExtensionID(); |
264 if (extension_id.empty()) | 260 if (extension_id.empty()) |
265 return v8::Undefined(); | 261 return v8::Undefined(); |
266 | 262 |
267 int matcher_id = args[0]->Int32Value(); | 263 int matcher_id = args[0]->Int32Value(); |
268 extensions::EventFilter& event_filter = g_event_filter.Get(); | 264 extensions::EventFilter& event_filter = g_event_filter.Get(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 static scoped_ptr<extensions::EventMatcher> ParseEventMatcher( | 324 static scoped_ptr<extensions::EventMatcher> ParseEventMatcher( |
329 base::DictionaryValue* filter_dict) { | 325 base::DictionaryValue* filter_dict) { |
330 return scoped_ptr<extensions::EventMatcher>(new extensions::EventMatcher( | 326 return scoped_ptr<extensions::EventMatcher>(new extensions::EventMatcher( |
331 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()))); | 327 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()))); |
332 } | 328 } |
333 }; | 329 }; |
334 | 330 |
335 } // namespace | 331 } // namespace |
336 | 332 |
337 // static | 333 // static |
338 ChromeV8Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) { | 334 ChromeV8Extension* EventBindings::Get(Dispatcher* dispatcher) { |
339 return new ExtensionImpl(dispatcher); | 335 return new ExtensionImpl(dispatcher); |
340 } | 336 } |
| 337 |
| 338 } // namespace extensions |
OLD | NEW |