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/render_view_impl.h" | 5 #include "content/renderer/render_view_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/json/json_reader.h" |
16 #include "base/json/json_writer.h" | 17 #include "base/json/json_writer.h" |
17 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
18 #include "base/message_loop_proxy.h" | 19 #include "base/message_loop_proxy.h" |
19 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
20 #include "base/path_service.h" | 21 #include "base/path_service.h" |
21 #include "base/process_util.h" | 22 #include "base/process_util.h" |
22 #include "base/string_number_conversions.h" | 23 #include "base/string_number_conversions.h" |
23 #include "base/string_piece.h" | 24 #include "base/string_piece.h" |
24 #include "base/string_split.h" | 25 #include "base/string_split.h" |
25 #include "base/string_util.h" | 26 #include "base/string_util.h" |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 339 |
339 static const float kScalingIncrement = 0.1f; | 340 static const float kScalingIncrement = 0.1f; |
340 | 341 |
341 static const float kScalingIncrementForGesture = 0.01f; | 342 static const float kScalingIncrementForGesture = 0.01f; |
342 | 343 |
343 static RenderViewImpl* FromRoutingID(int32 routing_id) { | 344 static RenderViewImpl* FromRoutingID(int32 routing_id) { |
344 return static_cast<RenderViewImpl*>( | 345 return static_cast<RenderViewImpl*>( |
345 ChildThread::current()->ResolveRoute(routing_id)); | 346 ChildThread::current()->ResolveRoute(routing_id)); |
346 } | 347 } |
347 | 348 |
| 349 static WebKit::WebFrame* FindFrameByID(WebKit::WebFrame* root, int frame_id) { |
| 350 for (WebFrame* frame = root; frame; frame = frame->traverseNext(false)) |
| 351 if (frame->identifier() == frame_id) |
| 352 return frame; |
| 353 return NULL; |
| 354 } |
| 355 |
348 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { | 356 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { |
349 WebVector<WebURL> urls; | 357 WebVector<WebURL> urls; |
350 ds->redirectChain(urls); | 358 ds->redirectChain(urls); |
351 result->reserve(urls.size()); | 359 result->reserve(urls.size()); |
352 for (size_t i = 0; i < urls.size(); ++i) | 360 for (size_t i = 0; i < urls.size(); ++i) |
353 result->push_back(urls[i]); | 361 result->push_back(urls[i]); |
354 } | 362 } |
355 | 363 |
356 // If |data_source| is non-null and has a DocumentState associated with it, | 364 // If |data_source| is non-null and has a DocumentState associated with it, |
357 // the AltErrorPageResourceFetcher is reset. | 365 // the AltErrorPageResourceFetcher is reset. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 if (!opener) { | 450 if (!opener) { |
443 return true; | 451 return true; |
444 } | 452 } |
445 | 453 |
446 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) | 454 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) |
447 return true; | 455 return true; |
448 } | 456 } |
449 return false; | 457 return false; |
450 } | 458 } |
451 | 459 |
| 460 // The frame tree for a renderer is serialized to JSON, so it can be sent to |
| 461 // the browser process. Each node in the tree is a DictionaryValue with three |
| 462 // properties: |
| 463 // * id - the frame identifier in this renderer |
| 464 // * name - the name of the frame, if one has been assigned |
| 465 // * subtree - a list of DictionaryValue objects for each frame that is |
| 466 // direct child of the current frame. This property can be omitted if |
| 467 // there are no direct child frames, so less data is transferred. |
| 468 static void ConstructFrameTree(WebKit::WebFrame* frame, |
| 469 WebKit::WebFrame* exclude_subtree, |
| 470 base::DictionaryValue* dict) { |
| 471 dict->SetString("name", UTF16ToUTF8(frame->assignedName()).c_str()); |
| 472 dict->SetInteger("id", frame->identifier()); |
| 473 |
| 474 WebFrame* child = frame->firstChild(); |
| 475 ListValue* children = new ListValue(); |
| 476 for (; child; child = child->nextSibling()) { |
| 477 if (child == exclude_subtree) |
| 478 continue; |
| 479 |
| 480 base::DictionaryValue* d = new base::DictionaryValue(); |
| 481 ConstructFrameTree(child, exclude_subtree, d); |
| 482 children->Append(d); |
| 483 } |
| 484 if (children->GetSize() > 0) { |
| 485 dict->Set("subtree", children); |
| 486 } |
| 487 } |
| 488 |
452 /////////////////////////////////////////////////////////////////////////////// | 489 /////////////////////////////////////////////////////////////////////////////// |
453 | 490 |
454 struct RenderViewImpl::PendingFileChooser { | 491 struct RenderViewImpl::PendingFileChooser { |
455 PendingFileChooser(const content::FileChooserParams& p, | 492 PendingFileChooser(const content::FileChooserParams& p, |
456 WebFileChooserCompletion* c) | 493 WebFileChooserCompletion* c) |
457 : params(p), | 494 : params(p), |
458 completion(c) { | 495 completion(c) { |
459 } | 496 } |
460 content::FileChooserParams params; | 497 content::FileChooserParams params; |
461 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. | 498 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 java_bridge_dispatcher_(NULL), | 588 java_bridge_dispatcher_(NULL), |
552 mouse_lock_dispatcher_(NULL), | 589 mouse_lock_dispatcher_(NULL), |
553 session_storage_namespace_id_(session_storage_namespace_id), | 590 session_storage_namespace_id_(session_storage_namespace_id), |
554 handling_select_range_(false), | 591 handling_select_range_(false), |
555 #if defined(OS_WIN) | 592 #if defined(OS_WIN) |
556 focused_plugin_id_(-1), | 593 focused_plugin_id_(-1), |
557 #endif | 594 #endif |
558 guest_to_embedder_channel_(guest_to_embedder_channel), | 595 guest_to_embedder_channel_(guest_to_embedder_channel), |
559 guest_pp_instance_(0), | 596 guest_pp_instance_(0), |
560 guest_uninitialized_context_(NULL), | 597 guest_uninitialized_context_(NULL), |
| 598 updating_frame_tree_(false), |
| 599 pending_frame_tree_update_(false), |
| 600 remote_process_id_(0), |
| 601 remote_routing_id_(0), |
561 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { | 602 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { |
562 set_throttle_input_events(renderer_prefs.throttle_input_events); | 603 set_throttle_input_events(renderer_prefs.throttle_input_events); |
563 routing_id_ = routing_id; | 604 routing_id_ = routing_id; |
564 surface_id_ = surface_id; | 605 surface_id_ = surface_id; |
565 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) | 606 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) |
566 opener_id_ = opener_id; | 607 opener_id_ = opener_id; |
567 | 608 |
568 // Ensure we start with a valid next_page_id_ from the browser. | 609 // Ensure we start with a valid next_page_id_ from the browser. |
569 DCHECK_GE(next_page_id_, 0); | 610 DCHECK_GE(next_page_id_, 0); |
570 | 611 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 686 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
646 if (command_line.HasSwitch(switches::kDomAutomationController)) | 687 if (command_line.HasSwitch(switches::kDomAutomationController)) |
647 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; | 688 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; |
648 | 689 |
649 ProcessViewLayoutFlags(command_line); | 690 ProcessViewLayoutFlags(command_line); |
650 | 691 |
651 content::GetContentClient()->renderer()->RenderViewCreated(this); | 692 content::GetContentClient()->renderer()->RenderViewCreated(this); |
652 | 693 |
653 // If we have an opener_id but we weren't created by a renderer, then | 694 // If we have an opener_id but we weren't created by a renderer, then |
654 // it's the browser asking us to set our opener to another RenderView. | 695 // it's the browser asking us to set our opener to another RenderView. |
655 // TODO(creis): This doesn't yet handle openers that are subframes. | |
656 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { | 696 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { |
657 RenderViewImpl* opener_view = FromRoutingID(opener_id); | 697 RenderViewImpl* opener_view = FromRoutingID(opener_id); |
658 if (opener_view) | 698 if (opener_view) |
659 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); | 699 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); |
660 } | 700 } |
661 | 701 |
662 // If we are initially swapped out, navigate to kSwappedOutURL. | 702 // If we are initially swapped out, navigate to kSwappedOutURL. |
663 // This ensures we are in a unique origin that others cannot script. | 703 // This ensures we are in a unique origin that others cannot script. |
664 if (is_swapped_out_) | 704 if (is_swapped_out_) |
665 NavigateToSwappedOutURL(); | 705 NavigateToSwappedOutURL(webview()->mainFrame(), NULL); |
666 } | 706 } |
667 | 707 |
668 RenderViewImpl::~RenderViewImpl() { | 708 RenderViewImpl::~RenderViewImpl() { |
669 history_page_ids_.clear(); | 709 history_page_ids_.clear(); |
670 | 710 |
671 if (decrement_shared_popup_at_destruction_) | 711 if (decrement_shared_popup_at_destruction_) |
672 shared_popup_counter_->data--; | 712 shared_popup_counter_->data--; |
673 | 713 |
674 // If file chooser is still waiting for answer, dispatch empty answer. | 714 // If file chooser is still waiting for answer, dispatch empty answer. |
675 while (!file_chooser_completions_.empty()) { | 715 while (!file_chooser_completions_.empty()) { |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) | 998 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) |
959 // TODO(viettrungluu): Move to a separate message filter. | 999 // TODO(viettrungluu): Move to a separate message filter. |
960 #if defined(OS_MACOSX) | 1000 #if defined(OS_MACOSX) |
961 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) | 1001 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) |
962 #endif | 1002 #endif |
963 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, | 1003 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, |
964 OnSetHistoryLengthAndPrune) | 1004 OnSetHistoryLengthAndPrune) |
965 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) | 1005 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) |
966 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) | 1006 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) |
967 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) | 1007 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) |
| 1008 IPC_MESSAGE_HANDLER(ViewMsg_FrameTree, OnFrameTree) |
968 | 1009 |
969 // Have the super handle all other messages. | 1010 // Have the super handle all other messages. |
970 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) | 1011 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) |
971 IPC_END_MESSAGE_MAP() | 1012 IPC_END_MESSAGE_MAP() |
972 | 1013 |
973 if (!msg_is_ok) { | 1014 if (!msg_is_ok) { |
974 // The message had a handler, but its deserialization failed. | 1015 // The message had a handler, but its deserialization failed. |
975 // Kill the renderer to avoid potential spoofing attacks. | 1016 // Kill the renderer to avoid potential spoofing attacks. |
976 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; | 1017 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; |
977 } | 1018 } |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 // NOTE: For now we're doing the safest thing, and sending out notification | 1902 // NOTE: For now we're doing the safest thing, and sending out notification |
1862 // when done loading. This currently isn't an issue as the favicon is only | 1903 // when done loading. This currently isn't an issue as the favicon is only |
1863 // displayed when done loading. Ideally we would send notification when | 1904 // displayed when done loading. Ideally we would send notification when |
1864 // finished parsing the head, but webkit doesn't support that yet. | 1905 // finished parsing the head, but webkit doesn't support that yet. |
1865 // The feed discovery code would also benefit from access to the head. | 1906 // The feed discovery code would also benefit from access to the head. |
1866 Send(new ViewHostMsg_DidStopLoading(routing_id_)); | 1907 Send(new ViewHostMsg_DidStopLoading(routing_id_)); |
1867 | 1908 |
1868 if (load_progress_tracker_ != NULL) | 1909 if (load_progress_tracker_ != NULL) |
1869 load_progress_tracker_->DidStopLoading(); | 1910 load_progress_tracker_->DidStopLoading(); |
1870 | 1911 |
| 1912 if (pending_frame_tree_update_) { |
| 1913 pending_frame_tree_update_ = false; |
| 1914 SendUpdatedFrameTree(webview()->mainFrame(), false); |
| 1915 } |
| 1916 |
1871 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); | 1917 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); |
1872 } | 1918 } |
1873 | 1919 |
1874 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, | 1920 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, |
1875 double load_progress) { | 1921 double load_progress) { |
1876 if (load_progress_tracker_ != NULL) | 1922 if (load_progress_tracker_ != NULL) |
1877 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); | 1923 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); |
1878 } | 1924 } |
1879 | 1925 |
1880 bool RenderViewImpl::isSmartInsertDeleteEnabled() { | 1926 bool RenderViewImpl::isSmartInsertDeleteEnabled() { |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2445 return NULL; | 2491 return NULL; |
2446 return new RendererWebApplicationCacheHostImpl( | 2492 return new RendererWebApplicationCacheHostImpl( |
2447 FromWebView(frame->view()), client, | 2493 FromWebView(frame->view()), client, |
2448 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); | 2494 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); |
2449 } | 2495 } |
2450 | 2496 |
2451 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { | 2497 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { |
2452 return &cookie_jar_; | 2498 return &cookie_jar_; |
2453 } | 2499 } |
2454 | 2500 |
| 2501 void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) { |
| 2502 if (is_loading_) { |
| 2503 pending_frame_tree_update_ = true; |
| 2504 return; |
| 2505 } |
| 2506 if (!updating_frame_tree_) { |
| 2507 SendUpdatedFrameTree(child, false); |
| 2508 } |
| 2509 } |
| 2510 |
2455 void RenderViewImpl::frameDetached(WebFrame* frame) { | 2511 void RenderViewImpl::frameDetached(WebFrame* frame) { |
| 2512 if (is_loading_) { |
| 2513 pending_frame_tree_update_ = true; |
| 2514 return; |
| 2515 } |
| 2516 if (!updating_frame_tree_) { |
| 2517 SendUpdatedFrameTree(frame, true); |
| 2518 } |
2456 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); | 2519 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); |
2457 } | 2520 } |
2458 | 2521 |
2459 void RenderViewImpl::willClose(WebFrame* frame) { | 2522 void RenderViewImpl::willClose(WebFrame* frame) { |
2460 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); | 2523 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); |
2461 } | 2524 } |
2462 | 2525 |
2463 void RenderViewImpl::loadURLExternally( | 2526 void RenderViewImpl::loadURLExternally( |
2464 WebFrame* frame, const WebURLRequest& request, | 2527 WebFrame* frame, const WebURLRequest& request, |
2465 WebNavigationPolicy policy) { | 2528 WebNavigationPolicy policy) { |
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3598 | 3661 |
3599 if (!context->Initialize( | 3662 if (!context->Initialize( |
3600 attributes, | 3663 attributes, |
3601 false /* bind generates resources */, | 3664 false /* bind generates resources */, |
3602 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_
INITIALIZE)) | 3665 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_
INITIALIZE)) |
3603 return NULL; | 3666 return NULL; |
3604 return context.release(); | 3667 return context.release(); |
3605 } | 3668 } |
3606 } | 3669 } |
3607 | 3670 |
| 3671 // The browser process needs to know the shape of the tree, as well as the names |
| 3672 // and ids of all frames. This allows it to properly route JavaScript messages |
| 3673 // across processes and frames. |
| 3674 // This function sends a those updates to the browser and updates the RVH |
| 3675 // corresponding to this object. It must be called on any events that modify |
| 3676 // the tree structure or the names of any frames. |
| 3677 void RenderViewImpl::SendUpdatedFrameTree( |
| 3678 WebKit::WebFrame* frame, bool exclude_subtree) { |
| 3679 std::string json; |
| 3680 WebFrame* f = frame->top(); |
| 3681 base::DictionaryValue tree; |
| 3682 |
| 3683 ConstructFrameTree(f, exclude_subtree ? frame : NULL, &tree); |
| 3684 base::JSONWriter::Write(&tree, &json); |
| 3685 |
| 3686 Send(new ViewHostMsg_FrameTree(routing_id_, json)); |
| 3687 } |
| 3688 |
3608 void RenderViewImpl::EnsureMediaStreamImpl() { | 3689 void RenderViewImpl::EnsureMediaStreamImpl() { |
3609 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. | 3690 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. |
3610 return; | 3691 return; |
3611 | 3692 |
3612 #if defined(ENABLE_WEBRTC) | 3693 #if defined(ENABLE_WEBRTC) |
3613 if (!p2p_socket_dispatcher_) | 3694 if (!p2p_socket_dispatcher_) |
3614 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); | 3695 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); |
3615 | 3696 |
3616 if (!media_stream_dispatcher_) | 3697 if (!media_stream_dispatcher_) |
3617 media_stream_dispatcher_ = new MediaStreamDispatcher(this); | 3698 media_stream_dispatcher_ = new MediaStreamDispatcher(this); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3813 } | 3894 } |
3814 delete channels; | 3895 delete channels; |
3815 } | 3896 } |
3816 | 3897 |
3817 int id = intents_host_->RegisterWebIntent(intentRequest); | 3898 int id = intents_host_->RegisterWebIntent(intentRequest); |
3818 Send(new IntentsHostMsg_WebIntentDispatch( | 3899 Send(new IntentsHostMsg_WebIntentDispatch( |
3819 routing_id_, intent_data, id)); | 3900 routing_id_, intent_data, id)); |
3820 } | 3901 } |
3821 | 3902 |
3822 bool RenderViewImpl::willCheckAndDispatchMessageEvent( | 3903 bool RenderViewImpl::willCheckAndDispatchMessageEvent( |
3823 WebKit::WebFrame* source, | 3904 WebKit::WebFrame* sourceFrame, |
| 3905 WebKit::WebFrame* targetFrame, |
3824 WebKit::WebSecurityOrigin target_origin, | 3906 WebKit::WebSecurityOrigin target_origin, |
3825 WebKit::WebDOMMessageEvent event) { | 3907 WebKit::WebDOMMessageEvent event) { |
3826 if (!is_swapped_out_) | 3908 if (!is_swapped_out_) |
3827 return false; | 3909 return false; |
3828 | 3910 |
3829 ViewMsg_PostMessage_Params params; | 3911 ViewMsg_PostMessage_Params params; |
3830 params.data = event.data().toString(); | 3912 params.data = event.data().toString(); |
3831 params.source_origin = event.origin(); | 3913 params.source_origin = event.origin(); |
3832 if (!target_origin.isNull()) | 3914 if (!target_origin.isNull()) |
3833 params.target_origin = target_origin.toString(); | 3915 params.target_origin = target_origin.toString(); |
3834 | 3916 |
3835 // Include the routing ID for the source frame, which the browser process | 3917 // Include the routing ID for the source frame, which the browser process |
3836 // will translate into the routing ID for the equivalent frame in the target | 3918 // will translate into the routing ID for the equivalent frame in the target |
3837 // process. | 3919 // process. |
3838 // TODO(creis): Support source subframes. | |
3839 params.source_routing_id = MSG_ROUTING_NONE; | 3920 params.source_routing_id = MSG_ROUTING_NONE; |
3840 RenderViewImpl* source_view = FromWebView(source->view()); | 3921 RenderViewImpl* source_view = FromWebView(sourceFrame->view()); |
3841 if (source_view) | 3922 if (source_view) |
3842 params.source_routing_id = source_view->routing_id(); | 3923 params.source_routing_id = source_view->routing_id(); |
| 3924 params.source_frame_id = sourceFrame->identifier(); |
| 3925 |
| 3926 // Include the process, route, and frame IDs of the target frame. This allows |
| 3927 // the browser to detect races between this message being sent and the target |
| 3928 // frame no longer being valid. |
| 3929 params.remote_process_id = remote_process_id_; |
| 3930 params.remote_routing_id = remote_routing_id_; |
| 3931 |
| 3932 std::map<int,int>::iterator it = frames_map_.find(targetFrame->identifier()); |
| 3933 if (it != frames_map_.end()) { |
| 3934 params.remote_frame_id = it->second; |
| 3935 } else { |
| 3936 params.remote_frame_id = 0; |
| 3937 } |
3843 | 3938 |
3844 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); | 3939 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); |
3845 return true; | 3940 return true; |
3846 } | 3941 } |
3847 | 3942 |
3848 void RenderViewImpl::willOpenSocketStream( | 3943 void RenderViewImpl::willOpenSocketStream( |
3849 WebSocketStreamHandle* handle) { | 3944 WebSocketStreamHandle* handle) { |
3850 SocketStreamHandleData::AddToHandle(handle, routing_id_); | 3945 SocketStreamHandleData::AddToHandle(handle, routing_id_); |
3851 } | 3946 } |
3852 | 3947 |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4562 | 4657 |
4563 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, | 4658 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, |
4564 const string16& jscript, | 4659 const string16& jscript, |
4565 int id, | 4660 int id, |
4566 bool notify_result) { | 4661 bool notify_result) { |
4567 EvaluateScript(frame_xpath, jscript, id, notify_result); | 4662 EvaluateScript(frame_xpath, jscript, id, notify_result); |
4568 } | 4663 } |
4569 | 4664 |
4570 void RenderViewImpl::OnPostMessageEvent( | 4665 void RenderViewImpl::OnPostMessageEvent( |
4571 const ViewMsg_PostMessage_Params& params) { | 4666 const ViewMsg_PostMessage_Params& params) { |
4572 // TODO(creis): Support sending to subframes. | 4667 // Find the frame, which is a target of this message. The source tags the |
4573 WebFrame* frame = webview()->mainFrame(); | 4668 // message with |remote_frame_id|, so use it to locate the frame. |
| 4669 WebFrame* frame = FindFrameByID(webview()->mainFrame(), |
| 4670 params.remote_frame_id); |
| 4671 if (!frame) |
| 4672 return; |
4574 | 4673 |
4575 // Find the source frame if it exists. | 4674 // Find the source frame if it exists. |
4576 // TODO(creis): Support source subframes. | |
4577 WebFrame* source_frame = NULL; | 4675 WebFrame* source_frame = NULL; |
4578 if (params.source_routing_id != MSG_ROUTING_NONE) { | 4676 if (params.source_routing_id != MSG_ROUTING_NONE) { |
4579 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); | 4677 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); |
4580 if (source_view) | 4678 if (source_view) |
4581 source_frame = source_view->webview()->mainFrame(); | 4679 source_frame = source_view->GetFrameByRemoteID(params.source_frame_id); |
4582 } | 4680 } |
4583 | 4681 |
4584 // Create an event with the message. The final parameter to initMessageEvent | 4682 // Create an event with the message. The final parameter to initMessageEvent |
4585 // is the last event ID, which is not used with postMessage. | 4683 // is the last event ID, which is not used with postMessage. |
4586 WebDOMEvent event = frame->document().createEvent("MessageEvent"); | 4684 WebDOMEvent event = frame->document().createEvent("MessageEvent"); |
4587 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); | 4685 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); |
4588 msg_event.initMessageEvent("message", | 4686 msg_event.initMessageEvent("message", |
4589 // |canBubble| and |cancellable| are always false | 4687 // |canBubble| and |cancellable| are always false |
4590 false, false, | 4688 false, false, |
4591 WebSerializedScriptValue::fromString(params.data), | 4689 WebSerializedScriptValue::fromString(params.data), |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4920 // Synchronously run the unload handler before sending the ACK. | 5018 // Synchronously run the unload handler before sending the ACK. |
4921 webview()->dispatchUnloadEvent(); | 5019 webview()->dispatchUnloadEvent(); |
4922 | 5020 |
4923 // Swap out and stop sending any IPC messages that are not ACKs. | 5021 // Swap out and stop sending any IPC messages that are not ACKs. |
4924 SetSwappedOut(true); | 5022 SetSwappedOut(true); |
4925 | 5023 |
4926 // Replace the page with a blank dummy URL. The unload handler will not be | 5024 // Replace the page with a blank dummy URL. The unload handler will not be |
4927 // run a second time, thanks to a check in FrameLoader::stopLoading. | 5025 // run a second time, thanks to a check in FrameLoader::stopLoading. |
4928 // TODO(creis): Need to add a better way to do this that avoids running the | 5026 // TODO(creis): Need to add a better way to do this that avoids running the |
4929 // beforeunload handler. For now, we just run it a second time silently. | 5027 // beforeunload handler. For now, we just run it a second time silently. |
4930 NavigateToSwappedOutURL(); | 5028 NavigateToSwappedOutURL(webview()->mainFrame(), NULL); |
4931 | 5029 |
4932 // Let WebKit know that this view is hidden so it can drop resources and | 5030 // Let WebKit know that this view is hidden so it can drop resources and |
4933 // stop compositing. | 5031 // stop compositing. |
4934 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); | 5032 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); |
4935 } | 5033 } |
4936 | 5034 |
4937 // Just echo back the params in the ACK. | 5035 // Just echo back the params in the ACK. |
4938 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); | 5036 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); |
4939 } | 5037 } |
4940 | 5038 |
4941 void RenderViewImpl::NavigateToSwappedOutURL() { | 5039 void RenderViewImpl::NavigateToSwappedOutURL( |
| 5040 WebKit::WebFrame* frame, |
| 5041 base::DictionaryValue* frame_tree) { |
4942 // We use loadRequest instead of loadHTMLString because the former commits | 5042 // We use loadRequest instead of loadHTMLString because the former commits |
4943 // synchronously. Otherwise a new navigation can interrupt the navigation | 5043 // synchronously. Otherwise a new navigation can interrupt the navigation |
4944 // to content::kSwappedOutURL. If that happens to be to the page we had been | 5044 // to content::kSwappedOutURL. If that happens to be to the page we had been |
4945 // showing, then WebKit will never send a commit and we'll be left spinning. | 5045 // showing, then WebKit will never send a commit and we'll be left spinning. |
4946 GURL swappedOutURL(content::kSwappedOutURL); | 5046 GURL swappedOutURL(content::kSwappedOutURL); |
4947 WebURLRequest request(swappedOutURL); | 5047 WebURLRequest request(swappedOutURL); |
4948 webview()->mainFrame()->loadRequest(request); | 5048 frame->loadRequest(request); |
| 5049 |
| 5050 // If a frame tree is specified, recursively recreate it using the data |
| 5051 // in the current DictionaryValue. |
| 5052 if (frame_tree == NULL) |
| 5053 return; |
| 5054 |
| 5055 string16 name; |
| 5056 if (frame_tree->GetString("name", &name) && name != string16()) |
| 5057 frame->setName(name); |
| 5058 |
| 5059 int remote_id; |
| 5060 if (frame_tree->GetInteger("id", &remote_id)) |
| 5061 frames_map_.insert(std::pair<int, int>(frame->identifier(), remote_id)); |
| 5062 |
| 5063 ListValue* children; |
| 5064 if (!frame_tree->GetList("subtree", &children)) |
| 5065 return; |
| 5066 |
| 5067 base::DictionaryValue* child; |
| 5068 for (size_t i = 0; i < children->GetSize(); ++i) { |
| 5069 if (!children->GetDictionary(i, &child)) |
| 5070 continue; |
| 5071 WebElement element = frame->document().createElement("iframe"); |
| 5072 if (frame->document().body().appendChild(element)) { |
| 5073 WebFrame* subframe = WebFrame::fromFrameOwnerElement(element); |
| 5074 if (subframe) { |
| 5075 NavigateToSwappedOutURL(subframe, child); |
| 5076 } |
| 5077 } |
| 5078 } |
4949 } | 5079 } |
4950 | 5080 |
4951 void RenderViewImpl::OnClosePage() { | 5081 void RenderViewImpl::OnClosePage() { |
4952 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); | 5082 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); |
4953 // TODO(creis): We'd rather use webview()->Close() here, but that currently | 5083 // TODO(creis): We'd rather use webview()->Close() here, but that currently |
4954 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs | 5084 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs |
4955 // in the onunload handler from appearing. For now, we're bypassing that and | 5085 // in the onunload handler from appearing. For now, we're bypassing that and |
4956 // calling the FrameLoader's CloseURL method directly. This should be | 5086 // calling the FrameLoader's CloseURL method directly. This should be |
4957 // revisited to avoid having two ways to close a page. Having a single way | 5087 // revisited to avoid having two ways to close a page. Having a single way |
4958 // to close that can run onunload is also useful for fixing | 5088 // to close that can run onunload is also useful for fixing |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5798 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { | 5928 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { |
5799 return !!RenderThreadImpl::current()->compositor_thread(); | 5929 return !!RenderThreadImpl::current()->compositor_thread(); |
5800 } | 5930 } |
5801 | 5931 |
5802 void RenderViewImpl::OnJavaBridgeInit() { | 5932 void RenderViewImpl::OnJavaBridgeInit() { |
5803 DCHECK(!java_bridge_dispatcher_); | 5933 DCHECK(!java_bridge_dispatcher_); |
5804 #if defined(ENABLE_JAVA_BRIDGE) | 5934 #if defined(ENABLE_JAVA_BRIDGE) |
5805 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); | 5935 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); |
5806 #endif | 5936 #endif |
5807 } | 5937 } |
| 5938 |
| 5939 void RenderViewImpl::OnFrameTree( |
| 5940 int process_id, |
| 5941 int route_id, |
| 5942 const std::string& frame_tree) { |
| 5943 base::DictionaryValue* frames = NULL; |
| 5944 scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree)); |
| 5945 if (tree.get() != NULL && tree->IsType(base::Value::TYPE_DICTIONARY)) |
| 5946 tree->GetAsDictionary(&frames); |
| 5947 |
| 5948 updating_frame_tree_ = true; |
| 5949 frames_map_.clear(); |
| 5950 |
| 5951 remote_process_id_ = process_id; |
| 5952 remote_routing_id_ = route_id; |
| 5953 NavigateToSwappedOutURL(webview()->mainFrame(), frames); |
| 5954 |
| 5955 updating_frame_tree_ = false; |
| 5956 } |
| 5957 |
| 5958 WebKit::WebFrame* RenderViewImpl::GetFrameByRemoteID(int remote_frame_id) { |
| 5959 WebKit::WebFrame* frame = NULL; |
| 5960 |
| 5961 std::map<int, int>::iterator it = frames_map_.find(remote_frame_id); |
| 5962 if (it == frames_map_.end()) |
| 5963 return NULL; |
| 5964 |
| 5965 for (WebFrame* f = webview()->mainFrame(); f; f = f->traverseNext(false)) |
| 5966 if (f->identifier() == it->second) |
| 5967 frame = f; |
| 5968 |
| 5969 return frame; |
| 5970 } |
OLD | NEW |