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 "content/renderer/browser_plugin/browser_plugin.h" | 5 #include "content/renderer/browser_plugin/browser_plugin.h" |
6 | 6 |
| 7 #include "base/json/json_string_value_serializer.h" |
7 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
9 #if defined (OS_WIN) | |
10 #include "base/sys_info.h" | |
11 #endif | |
12 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
13 #include "content/common/browser_plugin_messages.h" | 11 #include "content/common/browser_plugin_messages.h" |
14 #include "content/common/view_messages.h" | 12 #include "content/common/view_messages.h" |
15 #include "content/public/common/content_client.h" | 13 #include "content/public/common/content_client.h" |
16 #include "content/public/renderer/content_renderer_client.h" | 14 #include "content/public/renderer/content_renderer_client.h" |
17 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" | 15 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" |
18 #include "content/renderer/browser_plugin/browser_plugin_manager.h" | 16 #include "content/renderer/browser_plugin/browser_plugin_manager.h" |
19 #include "content/renderer/render_process_impl.h" | 17 #include "content/renderer/render_process_impl.h" |
20 #include "content/renderer/render_thread_impl.h" | 18 #include "content/renderer/render_thread_impl.h" |
| 19 #include "content/renderer/v8_value_converter_impl.h" |
21 #include "skia/ext/platform_canvas.h" | 20 #include "skia/ext/platform_canvas.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMCustomEvent.h" |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" |
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" |
29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" |
| 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" |
30 #include "webkit/plugins/sad_plugin.h" | 31 #include "webkit/plugins/sad_plugin.h" |
31 | 32 |
| 33 #if defined (OS_WIN) |
| 34 #include "base/sys_info.h" |
| 35 #endif |
| 36 |
32 using WebKit::WebCanvas; | 37 using WebKit::WebCanvas; |
33 using WebKit::WebPlugin; | 38 using WebKit::WebPlugin; |
34 using WebKit::WebPluginContainer; | 39 using WebKit::WebPluginContainer; |
35 using WebKit::WebPluginParams; | 40 using WebKit::WebPluginParams; |
36 using WebKit::WebPoint; | 41 using WebKit::WebPoint; |
37 using WebKit::WebString; | 42 using WebKit::WebString; |
38 using WebKit::WebRect; | 43 using WebKit::WebRect; |
39 using WebKit::WebURL; | 44 using WebKit::WebURL; |
40 using WebKit::WebVector; | 45 using WebKit::WebVector; |
41 | 46 |
(...skipping 11 matching lines...) Expand all Loading... |
53 const char kNewHeight[] = "newHeight"; | 58 const char kNewHeight[] = "newHeight"; |
54 const char kNewWidth[] = "newWidth"; | 59 const char kNewWidth[] = "newWidth"; |
55 const char kOldURL[] = "oldUrl"; | 60 const char kOldURL[] = "oldUrl"; |
56 const char kOldHeight[] = "oldHeight"; | 61 const char kOldHeight[] = "oldHeight"; |
57 const char kOldWidth[] = "oldWidth"; | 62 const char kOldWidth[] = "oldWidth"; |
58 const char kPartitionAttribute[] = "partition"; | 63 const char kPartitionAttribute[] = "partition"; |
59 const char kPersistPrefix[] = "persist:"; | 64 const char kPersistPrefix[] = "persist:"; |
60 const char kProcessId[] = "processId"; | 65 const char kProcessId[] = "processId"; |
61 const char kSizeChangedEventName[] = "sizechanged"; | 66 const char kSizeChangedEventName[] = "sizechanged"; |
62 const char kSrcAttribute[] = "src"; | 67 const char kSrcAttribute[] = "src"; |
63 const char kType[] = "type"; | 68 const char kReason[] = "reason"; |
64 const char kURL[] = "url"; | 69 const char kURL[] = "url"; |
65 | 70 |
66 static std::string TerminationStatusToString(base::TerminationStatus status) { | 71 static std::string TerminationStatusToString(base::TerminationStatus status) { |
67 switch (status) { | 72 switch (status) { |
68 case base::TERMINATION_STATUS_NORMAL_TERMINATION: | 73 case base::TERMINATION_STATUS_NORMAL_TERMINATION: |
69 return "normal"; | 74 return "normal"; |
70 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: | 75 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: |
71 return "abnormal"; | 76 return "abnormal"; |
72 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: | 77 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: |
73 return "killed"; | 78 return "killed"; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 content_window_routing_id_(MSG_ROUTING_NONE), | 110 content_window_routing_id_(MSG_ROUTING_NONE), |
106 plugin_focused_(false), | 111 plugin_focused_(false), |
107 embedder_focused_(false), | 112 embedder_focused_(false), |
108 visible_(true), | 113 visible_(true), |
109 size_changed_in_flight_(false), | 114 size_changed_in_flight_(false), |
110 current_nav_entry_index_(0), | 115 current_nav_entry_index_(0), |
111 nav_entry_count_(0) { | 116 nav_entry_count_(0) { |
112 BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); | 117 BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); |
113 bindings_.reset(new BrowserPluginBindings(this)); | 118 bindings_.reset(new BrowserPluginBindings(this)); |
114 | 119 |
115 InitializeEvents(); | |
116 | |
117 ParseAttributes(params); | 120 ParseAttributes(params); |
118 } | 121 } |
119 | 122 |
120 BrowserPlugin::~BrowserPlugin() { | 123 BrowserPlugin::~BrowserPlugin() { |
121 if (damage_buffer_) | 124 if (damage_buffer_) |
122 FreeDamageBuffer(); | 125 FreeDamageBuffer(); |
123 RemoveEventListeners(); | |
124 BrowserPluginManager::Get()->RemoveBrowserPlugin(instance_id_); | 126 BrowserPluginManager::Get()->RemoveBrowserPlugin(instance_id_); |
125 BrowserPluginManager::Get()->Send( | 127 BrowserPluginManager::Get()->Send( |
126 new BrowserPluginHostMsg_PluginDestroyed( | 128 new BrowserPluginHostMsg_PluginDestroyed( |
127 render_view_routing_id_, | 129 render_view_routing_id_, |
128 instance_id_)); | 130 instance_id_)); |
129 } | 131 } |
130 | 132 |
131 void BrowserPlugin::Cleanup() { | 133 void BrowserPlugin::Cleanup() { |
132 if (damage_buffer_) | 134 if (damage_buffer_) |
133 FreeDamageBuffer(); | 135 FreeDamageBuffer(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 instance_id_, | 218 instance_id_, |
217 auto_size_params, | 219 auto_size_params, |
218 resize_params)); | 220 resize_params)); |
219 if (damage_buffer_) | 221 if (damage_buffer_) |
220 FreeDamageBuffer(); | 222 FreeDamageBuffer(); |
221 damage_buffer_ = new_damage_buffer; | 223 damage_buffer_ = new_damage_buffer; |
222 } | 224 } |
223 | 225 |
224 void BrowserPlugin::SizeChangedDueToAutoSize(const gfx::Size& old_view_size) { | 226 void BrowserPlugin::SizeChangedDueToAutoSize(const gfx::Size& old_view_size) { |
225 size_changed_in_flight_ = false; | 227 size_changed_in_flight_ = false; |
226 if (!HasListeners(kSizeChangedEventName)) | |
227 return; | |
228 | 228 |
229 WebKit::WebElement plugin = container()->element(); | 229 std::map<std::string, base::Value*> props; |
230 v8::HandleScope handle_scope; | 230 props[kOldHeight] = base::Value::CreateIntegerValue(old_view_size.height()); |
231 v8::Context::Scope context_scope( | 231 props[kOldWidth] = base::Value::CreateIntegerValue(old_view_size.width()); |
232 plugin.document().frame()->mainWorldScriptContext()); | 232 props[kNewHeight] = base::Value::CreateIntegerValue(last_view_size_.height()); |
233 | 233 props[kNewWidth] = base::Value::CreateIntegerValue(last_view_size_.width()); |
234 // Construct the sizechanged event object. | 234 TriggerEvent(kSizeChangedEventName, &props); |
235 v8::Local<v8::Object> event = v8::Object::New(); | |
236 event->Set(v8::String::New(kOldHeight, sizeof(kOldHeight) - 1), | |
237 v8::Integer::New(old_view_size.height()), | |
238 v8::ReadOnly); | |
239 event->Set(v8::String::New(kOldWidth, sizeof(kOldWidth) - 1), | |
240 v8::Integer::New(old_view_size.width()), | |
241 v8::ReadOnly); | |
242 event->Set(v8::String::New(kNewHeight, sizeof(kNewHeight) - 1), | |
243 v8::Integer::New(last_view_size_.height()), | |
244 v8::ReadOnly); | |
245 event->Set(v8::String::New(kNewWidth, sizeof(kNewWidth) - 1), | |
246 v8::Integer::New(last_view_size_.width()), | |
247 v8::ReadOnly); | |
248 TriggerEvent(kSizeChangedEventName, &event); | |
249 } | 235 } |
250 | 236 |
251 void BrowserPlugin::SetMaxHeightAttribute(int max_height) { | 237 void BrowserPlugin::SetMaxHeightAttribute(int max_height) { |
252 if (max_height_ == max_height) | 238 if (max_height_ == max_height) |
253 return; | 239 return; |
254 max_height_ = max_height; | 240 max_height_ = max_height; |
255 if (!auto_size_) | 241 if (!auto_size_) |
256 return; | 242 return; |
257 UpdateGuestAutoSizeState(); | 243 UpdateGuestAutoSizeState(); |
258 } | 244 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // true, which prevents changing the 'partition' attribute. | 353 // true, which prevents changing the 'partition' attribute. |
368 SetSrcAttribute(src); | 354 SetSrcAttribute(src); |
369 } | 355 } |
370 | 356 |
371 float BrowserPlugin::GetDeviceScaleFactor() const { | 357 float BrowserPlugin::GetDeviceScaleFactor() const { |
372 if (!render_view_) | 358 if (!render_view_) |
373 return 1.0f; | 359 return 1.0f; |
374 return render_view_->GetWebView()->deviceScaleFactor(); | 360 return render_view_->GetWebView()->deviceScaleFactor(); |
375 } | 361 } |
376 | 362 |
377 void BrowserPlugin::InitializeEvents() { | 363 void BrowserPlugin::TriggerEvent(const std::string& event_name, |
378 event_listener_map_[kExitEventName] = EventListeners(); | 364 std::map<std::string, base::Value*>* props) { |
379 event_listener_map_[kLoadAbortEventName] = EventListeners(); | 365 if (!container() || !container()->element().document().frame()) |
380 event_listener_map_[kLoadCommitEventName] = EventListeners(); | 366 return; |
381 event_listener_map_[kLoadRedirectEventName] = EventListeners(); | 367 v8::HandleScope handle_scope; |
382 event_listener_map_[kLoadStartEventName] = EventListeners(); | 368 std::string json_string; |
383 event_listener_map_[kLoadStopEventName] = EventListeners(); | 369 if (props) { |
384 event_listener_map_[kSizeChangedEventName] = EventListeners(); | 370 base::DictionaryValue dict; |
385 } | 371 for (std::map<std::string, base::Value*>::iterator iter = props->begin(), |
| 372 end = props->end(); iter != end; ++iter) { |
| 373 dict.Set(iter->first, iter->second); |
| 374 } |
386 | 375 |
387 void BrowserPlugin::RemoveEventListeners() { | 376 JSONStringValueSerializer serializer(&json_string); |
388 EventListenerMap::iterator event_listener_map_iter = | 377 if (!serializer.Serialize(dict)) |
389 event_listener_map_.begin(); | 378 return; |
390 for (; event_listener_map_iter != event_listener_map_.end(); | |
391 ++event_listener_map_iter) { | |
392 EventListeners& listeners = | |
393 event_listener_map_[event_listener_map_iter->first]; | |
394 EventListeners::iterator it = listeners.begin(); | |
395 for (; it != listeners.end(); ++it) { | |
396 it->Dispose(); | |
397 } | |
398 } | |
399 event_listener_map_.clear(); | |
400 } | |
401 | |
402 bool BrowserPlugin::IsValidEvent(const std::string& event_name) { | |
403 return event_listener_map_.find(event_name) != event_listener_map_.end(); | |
404 } | |
405 | |
406 void BrowserPlugin::TriggerEvent(const std::string& event_name, | |
407 v8::Local<v8::Object>* event) { | |
408 WebKit::WebElement plugin = container()->element(); | |
409 | |
410 const EventListeners& listeners = event_listener_map_[event_name.c_str()]; | |
411 // A v8::Local copy of the listeners is created from the v8::Persistent | |
412 // listeners before firing them. This is to ensure that if one of these | |
413 // listeners mutate the list of listeners (by calling | |
414 // addEventListener/removeEventListener), this local copy is not affected. | |
415 // This means if you mutate the list of listeners for an event X while event X | |
416 // is firing, the mutation is deferred until all current listeners for X have | |
417 // fired. | |
418 EventListenersLocal listeners_local; | |
419 listeners_local.reserve(listeners.size()); | |
420 for (EventListeners::const_iterator it = listeners.begin(); | |
421 it != listeners.end(); | |
422 ++it) { | |
423 listeners_local.push_back(v8::Local<v8::Function>::New(*it)); | |
424 } | 379 } |
425 | 380 |
426 (*event)->Set(v8::String::New("name"), | 381 WebKit::WebFrame* frame = container()->element().document().frame(); |
427 v8::String::New(event_name.c_str(), event_name.size()), | 382 WebKit::WebDOMEvent dom_event = frame->document().createEvent("CustomEvent"); |
428 v8::ReadOnly); | 383 WebKit::WebDOMCustomEvent event = dom_event.to<WebKit::WebDOMCustomEvent>(); |
429 v8::Local<v8::Value> argv[] = { *event }; | 384 |
430 for (EventListenersLocal::const_iterator it = listeners_local.begin(); | 385 // The events triggered directly from the plugin <object> are internal events |
431 it != listeners_local.end(); | 386 // whose implementation details can (and likely will) change over time. The |
432 ++it) { | 387 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a |
433 WebKit::WebFrame* frame = plugin.document().frame(); | 388 // more appropriate (and stable) event to the consumers as part of the API. |
434 if (!frame) | 389 std::string internal_name = base::StringPrintf("-internal-%s", |
435 break; | 390 event_name.c_str()); |
436 frame->callFunctionEvenIfScriptDisabled(*it, v8::Object::New(), 1, argv); | 391 event.initCustomEvent( |
437 } | 392 WebKit::WebString::fromUTF8(internal_name.c_str()), |
| 393 false, false, |
| 394 WebKit::WebSerializedScriptValue::serialize( |
| 395 v8::String::New(json_string.c_str(), json_string.size()))); |
| 396 container()->element().dispatchEvent(event); |
438 } | 397 } |
439 | 398 |
440 void BrowserPlugin::Back() { | 399 void BrowserPlugin::Back() { |
441 if (!navigate_src_sent_) | 400 if (!navigate_src_sent_) |
442 return; | 401 return; |
443 BrowserPluginManager::Get()->Send( | 402 BrowserPluginManager::Get()->Send( |
444 new BrowserPluginHostMsg_Go(render_view_routing_id_, | 403 new BrowserPluginHostMsg_Go(render_view_routing_id_, |
445 instance_id_, -1)); | 404 instance_id_, -1)); |
446 } | 405 } |
447 | 406 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( | 523 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( |
565 render_view_routing_id_, | 524 render_view_routing_id_, |
566 instance_id_, | 525 instance_id_, |
567 message_id, | 526 message_id, |
568 gfx::Size())); | 527 gfx::Size())); |
569 } | 528 } |
570 | 529 |
571 void BrowserPlugin::GuestGone(int process_id, base::TerminationStatus status) { | 530 void BrowserPlugin::GuestGone(int process_id, base::TerminationStatus status) { |
572 // We fire the event listeners before painting the sad graphic to give the | 531 // We fire the event listeners before painting the sad graphic to give the |
573 // developer an opportunity to display an alternative overlay image on crash. | 532 // developer an opportunity to display an alternative overlay image on crash. |
574 if (HasListeners(kExitEventName)) { | 533 std::string termination_status = TerminationStatusToString(status); |
575 WebKit::WebElement plugin = container()->element(); | 534 std::map<std::string, base::Value*> props; |
576 v8::HandleScope handle_scope; | 535 props[kProcessId] = base::Value::CreateIntegerValue(process_id); |
577 v8::Context::Scope context_scope( | 536 props[kReason] = base::Value::CreateStringValue(termination_status); |
578 plugin.document().frame()->mainWorldScriptContext()); | |
579 | 537 |
580 // Construct the exit event object. | 538 // Event listeners may remove the BrowserPlugin from the document. If that |
581 v8::Local<v8::Object> event = v8::Object::New(); | 539 // happens, the BrowserPlugin will be scheduled for later deletion (see |
582 event->Set(v8::String::New(kProcessId, sizeof(kProcessId) - 1), | 540 // BrowserPlugin::destroy()). That will clear the container_ reference, |
583 v8::Integer::New(process_id), | 541 // but leave other member variables valid below. |
584 v8::ReadOnly); | 542 TriggerEvent(kExitEventName, &props); |
585 std::string termination_status = TerminationStatusToString(status); | 543 |
586 event->Set(v8::String::New(kType, sizeof(kType) - 1), | |
587 v8::String::New(termination_status.data(), | |
588 termination_status.size()), | |
589 v8::ReadOnly); | |
590 // Event listeners may remove the BrowserPlugin from the document. If that | |
591 // happens, the BrowserPlugin will be scheduled for later deletion (see | |
592 // BrowserPlugin::destroy()). That will clear the container_ reference, | |
593 // but leave other member variables valid below. | |
594 TriggerEvent(kExitEventName, &event); | |
595 } | |
596 guest_crashed_ = true; | 544 guest_crashed_ = true; |
597 // We won't paint the contents of the current backing store again so we might | 545 // We won't paint the contents of the current backing store again so we might |
598 // as well toss it out and save memory. | 546 // as well toss it out and save memory. |
599 backing_store_.reset(); | 547 backing_store_.reset(); |
600 // If the BrowserPlugin is scheduled to be deleted, then container_ will be | 548 // If the BrowserPlugin is scheduled to be deleted, then container_ will be |
601 // NULL so we shouldn't attempt to access it. | 549 // NULL so we shouldn't attempt to access it. |
602 if (container_) | 550 if (container_) |
603 container_->invalidate(); | 551 container_->invalidate(); |
604 } | 552 } |
605 | 553 |
606 void BrowserPlugin::LoadStart(const GURL& url, bool is_top_level) { | 554 void BrowserPlugin::LoadStart(const GURL& url, bool is_top_level) { |
607 if (!HasListeners(kLoadStartEventName)) | 555 std::map<std::string, base::Value*> props; |
608 return; | 556 props[kURL] = base::Value::CreateStringValue(url.spec()); |
| 557 props[kIsTopLevel] = base::Value::CreateBooleanValue(is_top_level); |
609 | 558 |
610 WebKit::WebElement plugin = container()->element(); | 559 TriggerEvent(kLoadStartEventName, &props); |
611 v8::HandleScope handle_scope; | |
612 v8::Context::Scope context_scope( | |
613 plugin.document().frame()->mainWorldScriptContext()); | |
614 | |
615 // Construct the loadStart event object. | |
616 v8::Local<v8::Object> event = v8::Object::New(); | |
617 event->Set(v8::String::New(kURL, sizeof(kURL) - 1), | |
618 v8::String::New(url.spec().data(), url.spec().size()), | |
619 v8::ReadOnly); | |
620 event->Set(v8::String::New(kIsTopLevel, sizeof(kIsTopLevel) - 1), | |
621 v8::Boolean::New(is_top_level), | |
622 v8::ReadOnly); | |
623 TriggerEvent(kLoadStartEventName, &event); | |
624 } | 560 } |
625 | 561 |
626 void BrowserPlugin::LoadCommit( | 562 void BrowserPlugin::LoadCommit( |
627 const BrowserPluginMsg_LoadCommit_Params& params) { | 563 const BrowserPluginMsg_LoadCommit_Params& params) { |
628 // If the guest has just committed a new navigation then it is no longer | 564 // If the guest has just committed a new navigation then it is no longer |
629 // crashed. | 565 // crashed. |
630 guest_crashed_ = false; | 566 guest_crashed_ = false; |
631 src_ = params.url.spec(); | 567 src_ = params.url.spec(); |
632 process_id_ = params.process_id; | 568 process_id_ = params.process_id; |
633 current_nav_entry_index_ = params.current_entry_index; | 569 current_nav_entry_index_ = params.current_entry_index; |
634 nav_entry_count_ = params.entry_count; | 570 nav_entry_count_ = params.entry_count; |
635 | 571 |
636 if (!HasListeners(kLoadCommitEventName)) | 572 std::map<std::string, base::Value*> props; |
637 return; | 573 props[kURL] = base::Value::CreateStringValue(src_); |
638 | 574 props[kIsTopLevel] = base::Value::CreateBooleanValue(params.is_top_level); |
639 WebKit::WebElement plugin = container()->element(); | 575 TriggerEvent(kLoadCommitEventName, &props); |
640 v8::HandleScope handle_scope; | |
641 v8::Context::Scope context_scope( | |
642 plugin.document().frame()->mainWorldScriptContext()); | |
643 | |
644 // Construct the loadCommit event object. | |
645 v8::Local<v8::Object> event = v8::Object::New(); | |
646 event->Set(v8::String::New(kURL, sizeof(kURL) - 1), | |
647 v8::String::New(src_.data(), src_.size()), | |
648 v8::ReadOnly); | |
649 event->Set(v8::String::New(kIsTopLevel, sizeof(kIsTopLevel) - 1), | |
650 v8::Boolean::New(params.is_top_level), | |
651 v8::ReadOnly); | |
652 | |
653 TriggerEvent(kLoadCommitEventName, &event); | |
654 } | 576 } |
655 | 577 |
656 void BrowserPlugin::LoadStop() { | 578 void BrowserPlugin::LoadStop() { |
657 if (!HasListeners(kLoadStopEventName)) | |
658 return; | |
659 | |
660 WebKit::WebElement plugin = container()->element(); | |
661 v8::HandleScope handle_scope; | |
662 v8::Context::Scope context_scope( | |
663 plugin.document().frame()->mainWorldScriptContext()); | |
664 | |
665 // Construct the loadStop event object. | 579 // Construct the loadStop event object. |
666 v8::Local<v8::Object> event = v8::Object::New(); | 580 TriggerEvent(kLoadStopEventName, NULL); |
667 TriggerEvent(kLoadStopEventName, &event); | |
668 } | 581 } |
669 | 582 |
670 void BrowserPlugin::LoadAbort(const GURL& url, | 583 void BrowserPlugin::LoadAbort(const GURL& url, |
671 bool is_top_level, | 584 bool is_top_level, |
672 const std::string& type) { | 585 const std::string& type) { |
673 if (!HasListeners(kLoadAbortEventName)) | 586 std::map<std::string, base::Value*> props; |
674 return; | 587 props[kURL] = base::Value::CreateStringValue(url.spec()); |
675 | 588 props[kIsTopLevel] = base::Value::CreateBooleanValue(is_top_level); |
676 WebKit::WebElement plugin = container()->element(); | 589 props[kReason] = base::Value::CreateStringValue(type); |
677 v8::HandleScope handle_scope; | 590 TriggerEvent(kLoadAbortEventName, &props); |
678 v8::Context::Scope context_scope( | |
679 plugin.document().frame()->mainWorldScriptContext()); | |
680 | |
681 // Construct the loadAbort event object. | |
682 v8::Local<v8::Object> event = v8::Object::New(); | |
683 event->Set(v8::String::New(kURL, sizeof(kURL) - 1), | |
684 v8::String::New(url.spec().data(), url.spec().size()), | |
685 v8::ReadOnly); | |
686 event->Set(v8::String::New(kIsTopLevel, sizeof(kIsTopLevel) - 1), | |
687 v8::Boolean::New(is_top_level), | |
688 v8::ReadOnly); | |
689 event->Set(v8::String::New(kType, sizeof(kType) - 1), | |
690 v8::String::New(type.data(), type.size()), | |
691 v8::ReadOnly); | |
692 | |
693 TriggerEvent(kLoadAbortEventName, &event); | |
694 } | 591 } |
695 | 592 |
696 void BrowserPlugin::LoadRedirect(const GURL& old_url, | 593 void BrowserPlugin::LoadRedirect(const GURL& old_url, |
697 const GURL& new_url, | 594 const GURL& new_url, |
698 bool is_top_level) { | 595 bool is_top_level) { |
699 if (!HasListeners(kLoadRedirectEventName)) | 596 std::map<std::string, base::Value*> props; |
700 return; | 597 props[kOldURL] = base::Value::CreateStringValue(old_url.spec()); |
701 | 598 props[kNewURL] = base::Value::CreateStringValue(new_url.spec()); |
702 WebKit::WebElement plugin = container()->element(); | 599 props[kIsTopLevel] = base::Value::CreateBooleanValue(is_top_level); |
703 v8::HandleScope handle_scope; | 600 TriggerEvent(kLoadRedirectEventName, &props); |
704 v8::Context::Scope context_scope( | |
705 plugin.document().frame()->mainWorldScriptContext()); | |
706 | |
707 // Construct the loadRedirect event object. | |
708 v8::Local<v8::Object> event = v8::Object::New(); | |
709 event->Set(v8::String::New(kOldURL, sizeof(kOldURL) - 1), | |
710 v8::String::New(old_url.spec().data(), old_url.spec().size()), | |
711 v8::ReadOnly); | |
712 event->Set(v8::String::New(kNewURL, sizeof(kNewURL) - 1), | |
713 v8::String::New(new_url.spec().data(), new_url.spec().size()), | |
714 v8::ReadOnly); | |
715 event->Set(v8::String::New(kIsTopLevel, sizeof(kIsTopLevel) - 1), | |
716 v8::Boolean::New(is_top_level), | |
717 v8::ReadOnly); | |
718 | |
719 TriggerEvent(kLoadRedirectEventName, &event); | |
720 } | 601 } |
721 | 602 |
722 void BrowserPlugin::AdvanceFocus(bool reverse) { | 603 void BrowserPlugin::AdvanceFocus(bool reverse) { |
723 DCHECK(render_view_); | 604 DCHECK(render_view_); |
724 render_view_->GetWebView()->advanceFocus(reverse); | 605 render_view_->GetWebView()->advanceFocus(reverse); |
725 } | 606 } |
726 | 607 |
727 void BrowserPlugin::SetEmbedderFocus(bool focused) { | 608 void BrowserPlugin::SetEmbedderFocus(bool focused) { |
728 if (embedder_focused_ == focused) | 609 if (embedder_focused_ == focused) |
729 return; | 610 return; |
(...skipping 22 matching lines...) Expand all Loading... |
752 void BrowserPlugin::GuestContentWindowReady(int content_window_routing_id) { | 633 void BrowserPlugin::GuestContentWindowReady(int content_window_routing_id) { |
753 DCHECK(content_window_routing_id != MSG_ROUTING_NONE); | 634 DCHECK(content_window_routing_id != MSG_ROUTING_NONE); |
754 content_window_routing_id_ = content_window_routing_id; | 635 content_window_routing_id_ = content_window_routing_id; |
755 } | 636 } |
756 | 637 |
757 void BrowserPlugin::SetAcceptTouchEvents(bool accept) { | 638 void BrowserPlugin::SetAcceptTouchEvents(bool accept) { |
758 if (container()) | 639 if (container()) |
759 container()->setIsAcceptingTouchEvents(accept); | 640 container()->setIsAcceptingTouchEvents(accept); |
760 } | 641 } |
761 | 642 |
762 bool BrowserPlugin::HasListeners(const std::string& event_name) { | |
763 return IsValidEvent(event_name) && | |
764 !event_listener_map_[event_name].empty(); | |
765 } | |
766 | |
767 bool BrowserPlugin::AddEventListener(const std::string& event_name, | |
768 v8::Local<v8::Function> function) { | |
769 if (!IsValidEvent(event_name)) | |
770 return false; | |
771 EventListeners& listeners = event_listener_map_[event_name]; | |
772 for (unsigned int i = 0; i < listeners.size(); ++i) { | |
773 if (listeners[i] == function) | |
774 return false; | |
775 } | |
776 v8::Persistent<v8::Function> persistent_function = | |
777 v8::Persistent<v8::Function>::New(function); | |
778 listeners.push_back(persistent_function); | |
779 return true; | |
780 } | |
781 | |
782 bool BrowserPlugin::RemoveEventListener(const std::string& event_name, | |
783 v8::Local<v8::Function> function) { | |
784 if (!HasListeners(event_name)) | |
785 return false; | |
786 | |
787 EventListeners& listeners = event_listener_map_[event_name]; | |
788 EventListeners::iterator it = listeners.begin(); | |
789 for (; it != listeners.end(); ++it) { | |
790 if (*it == function) { | |
791 it->Dispose(); | |
792 listeners.erase(it); | |
793 return true; | |
794 } | |
795 } | |
796 return false; | |
797 } | |
798 | |
799 WebKit::WebPluginContainer* BrowserPlugin::container() const { | 643 WebKit::WebPluginContainer* BrowserPlugin::container() const { |
800 return container_; | 644 return container_; |
801 } | 645 } |
802 | 646 |
803 bool BrowserPlugin::initialize(WebPluginContainer* container) { | 647 bool BrowserPlugin::initialize(WebPluginContainer* container) { |
804 container_ = container; | 648 container_ = container; |
805 return true; | 649 return true; |
806 } | 650 } |
807 | 651 |
808 void BrowserPlugin::destroy() { | 652 void BrowserPlugin::destroy() { |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 void* notify_data) { | 923 void* notify_data) { |
1080 } | 924 } |
1081 | 925 |
1082 void BrowserPlugin::didFailLoadingFrameRequest( | 926 void BrowserPlugin::didFailLoadingFrameRequest( |
1083 const WebKit::WebURL& url, | 927 const WebKit::WebURL& url, |
1084 void* notify_data, | 928 void* notify_data, |
1085 const WebKit::WebURLError& error) { | 929 const WebKit::WebURLError& error) { |
1086 } | 930 } |
1087 | 931 |
1088 } // namespace content | 932 } // namespace content |
OLD | NEW |