Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: content/renderer/render_view_impl.cc

Issue 10827078: Support frame tree propagation between renderers in the same browsing instance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Let the reviews begin :) Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 static void FrameTree(WebKit::WebFrame* frame,
461 WebKit::WebFrame* exclude_subtree,
462 base::DictionaryValue* dict) {
463 dict->SetString("name", UTF16ToUTF8(frame->assignedName()).c_str());
464 dict->SetInteger("id", frame->identifier());
465
466 WebFrame* child = frame->firstChild();
467 ListValue* children = new ListValue();
468 for (; child; child = child->nextSibling()) {
469 if (child == exclude_subtree)
470 continue;
471
472 base::DictionaryValue* d = new base::DictionaryValue();
473 FrameTree(child, exclude_subtree, d);
474 children->Append(d);
475 }
476 if (children->GetSize() > 0) {
477 dict->Set("subtree", children);
478 }
479 }
480
452 /////////////////////////////////////////////////////////////////////////////// 481 ///////////////////////////////////////////////////////////////////////////////
453 482
454 struct RenderViewImpl::PendingFileChooser { 483 struct RenderViewImpl::PendingFileChooser {
455 PendingFileChooser(const content::FileChooserParams& p, 484 PendingFileChooser(const content::FileChooserParams& p,
456 WebFileChooserCompletion* c) 485 WebFileChooserCompletion* c)
457 : params(p), 486 : params(p),
458 completion(c) { 487 completion(c) {
459 } 488 }
460 content::FileChooserParams params; 489 content::FileChooserParams params;
461 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. 490 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 java_bridge_dispatcher_(NULL), 580 java_bridge_dispatcher_(NULL),
552 mouse_lock_dispatcher_(NULL), 581 mouse_lock_dispatcher_(NULL),
553 session_storage_namespace_id_(session_storage_namespace_id), 582 session_storage_namespace_id_(session_storage_namespace_id),
554 handling_select_range_(false), 583 handling_select_range_(false),
555 #if defined(OS_WIN) 584 #if defined(OS_WIN)
556 focused_plugin_id_(-1), 585 focused_plugin_id_(-1),
557 #endif 586 #endif
558 guest_to_embedder_channel_(guest_to_embedder_channel), 587 guest_to_embedder_channel_(guest_to_embedder_channel),
559 guest_pp_instance_(0), 588 guest_pp_instance_(0),
560 guest_uninitialized_context_(NULL), 589 guest_uninitialized_context_(NULL),
590 updating_frame_tree_(false),
591 pending_frame_tree_update_(false),
592 remote_process_id_(0),
593 remote_routing_id_(0),
561 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { 594 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) {
562 set_throttle_input_events(renderer_prefs.throttle_input_events); 595 set_throttle_input_events(renderer_prefs.throttle_input_events);
563 routing_id_ = routing_id; 596 routing_id_ = routing_id;
564 surface_id_ = surface_id; 597 surface_id_ = surface_id;
565 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) 598 if (opener_id != MSG_ROUTING_NONE && is_renderer_created)
566 opener_id_ = opener_id; 599 opener_id_ = opener_id;
567 600
568 // Ensure we start with a valid next_page_id_ from the browser. 601 // Ensure we start with a valid next_page_id_ from the browser.
569 DCHECK_GE(next_page_id_, 0); 602 DCHECK_GE(next_page_id_, 0);
570 603
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 678 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
646 if (command_line.HasSwitch(switches::kDomAutomationController)) 679 if (command_line.HasSwitch(switches::kDomAutomationController))
647 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; 680 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION;
648 681
649 ProcessViewLayoutFlags(command_line); 682 ProcessViewLayoutFlags(command_line);
650 683
651 content::GetContentClient()->renderer()->RenderViewCreated(this); 684 content::GetContentClient()->renderer()->RenderViewCreated(this);
652 685
653 // If we have an opener_id but we weren't created by a renderer, then 686 // 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. 687 // 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) { 688 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) {
657 RenderViewImpl* opener_view = FromRoutingID(opener_id); 689 RenderViewImpl* opener_view = FromRoutingID(opener_id);
658 if (opener_view) 690 if (opener_view)
659 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); 691 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame());
660 } 692 }
661 693
662 // If we are initially swapped out, navigate to kSwappedOutURL. 694 // If we are initially swapped out, navigate to kSwappedOutURL.
663 // This ensures we are in a unique origin that others cannot script. 695 // This ensures we are in a unique origin that others cannot script.
664 if (is_swapped_out_) 696 if (is_swapped_out_)
665 NavigateToSwappedOutURL(); 697 NavigateToSwappedOutURL(webview()->mainFrame(), NULL);
666 } 698 }
667 699
668 RenderViewImpl::~RenderViewImpl() { 700 RenderViewImpl::~RenderViewImpl() {
669 history_page_ids_.clear(); 701 history_page_ids_.clear();
670 702
671 if (decrement_shared_popup_at_destruction_) 703 if (decrement_shared_popup_at_destruction_)
672 shared_popup_counter_->data--; 704 shared_popup_counter_->data--;
673 705
674 // If file chooser is still waiting for answer, dispatch empty answer. 706 // If file chooser is still waiting for answer, dispatch empty answer.
675 while (!file_chooser_completions_.empty()) { 707 while (!file_chooser_completions_.empty()) {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) 990 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
959 // TODO(viettrungluu): Move to a separate message filter. 991 // TODO(viettrungluu): Move to a separate message filter.
960 #if defined(OS_MACOSX) 992 #if defined(OS_MACOSX)
961 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) 993 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize)
962 #endif 994 #endif
963 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, 995 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
964 OnSetHistoryLengthAndPrune) 996 OnSetHistoryLengthAndPrune)
965 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) 997 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
966 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) 998 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
967 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) 999 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode)
1000 IPC_MESSAGE_HANDLER(ViewMsg_FrameTree, OnFrameTree)
968 1001
969 // Have the super handle all other messages. 1002 // Have the super handle all other messages.
970 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) 1003 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
971 IPC_END_MESSAGE_MAP() 1004 IPC_END_MESSAGE_MAP()
972 1005
973 if (!msg_is_ok) { 1006 if (!msg_is_ok) {
974 // The message had a handler, but its deserialization failed. 1007 // The message had a handler, but its deserialization failed.
975 // Kill the renderer to avoid potential spoofing attacks. 1008 // Kill the renderer to avoid potential spoofing attacks.
976 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; 1009 CHECK(false) << "Unable to deserialize message in RenderViewImpl.";
977 } 1010 }
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 // NOTE: For now we're doing the safest thing, and sending out notification 1894 // 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 1895 // 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 1896 // displayed when done loading. Ideally we would send notification when
1864 // finished parsing the head, but webkit doesn't support that yet. 1897 // finished parsing the head, but webkit doesn't support that yet.
1865 // The feed discovery code would also benefit from access to the head. 1898 // The feed discovery code would also benefit from access to the head.
1866 Send(new ViewHostMsg_DidStopLoading(routing_id_)); 1899 Send(new ViewHostMsg_DidStopLoading(routing_id_));
1867 1900
1868 if (load_progress_tracker_ != NULL) 1901 if (load_progress_tracker_ != NULL)
1869 load_progress_tracker_->DidStopLoading(); 1902 load_progress_tracker_->DidStopLoading();
1870 1903
1904 if (pending_frame_tree_update_) {
1905 pending_frame_tree_update_ = false;
1906 std::string frame_tree = ConstructFrameTree(webview()->mainFrame(), false);
1907 Send(new ViewHostMsg_FrameTree(routing_id_, frame_tree));
1908 }
1909
1871 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); 1910 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading());
1872 } 1911 }
1873 1912
1874 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, 1913 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame,
1875 double load_progress) { 1914 double load_progress) {
1876 if (load_progress_tracker_ != NULL) 1915 if (load_progress_tracker_ != NULL)
1877 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); 1916 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
1878 } 1917 }
1879 1918
1880 bool RenderViewImpl::isSmartInsertDeleteEnabled() { 1919 bool RenderViewImpl::isSmartInsertDeleteEnabled() {
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 return NULL; 2484 return NULL;
2446 return new RendererWebApplicationCacheHostImpl( 2485 return new RendererWebApplicationCacheHostImpl(
2447 FromWebView(frame->view()), client, 2486 FromWebView(frame->view()), client,
2448 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); 2487 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
2449 } 2488 }
2450 2489
2451 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { 2490 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) {
2452 return &cookie_jar_; 2491 return &cookie_jar_;
2453 } 2492 }
2454 2493
2494 void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) {
2495 if (is_loading_) {
2496 pending_frame_tree_update_ = true;
2497 return;
2498 }
2499 if (!updating_frame_tree_) {
2500 std::string frame_tree = ConstructFrameTree(child, false);
2501 Send(new ViewHostMsg_FrameTree(routing_id_, frame_tree));
2502 }
2503 }
2504
2455 void RenderViewImpl::frameDetached(WebFrame* frame) { 2505 void RenderViewImpl::frameDetached(WebFrame* frame) {
2506 if (is_loading_) {
2507 pending_frame_tree_update_ = true;
2508 return;
2509 }
2510 if (!updating_frame_tree_) {
2511 std::string frame_tree = ConstructFrameTree(frame, true);
2512 Send(new ViewHostMsg_FrameTree(routing_id_, frame_tree));
2513 }
2456 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); 2514 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
2457 } 2515 }
2458 2516
2459 void RenderViewImpl::willClose(WebFrame* frame) { 2517 void RenderViewImpl::willClose(WebFrame* frame) {
2460 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); 2518 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
2461 } 2519 }
2462 2520
2463 void RenderViewImpl::loadURLExternally( 2521 void RenderViewImpl::loadURLExternally(
2464 WebFrame* frame, const WebURLRequest& request, 2522 WebFrame* frame, const WebURLRequest& request,
2465 WebNavigationPolicy policy) { 2523 WebNavigationPolicy policy) {
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3598 3656
3599 if (!context->Initialize( 3657 if (!context->Initialize(
3600 attributes, 3658 attributes,
3601 false /* bind generates resources */, 3659 false /* bind generates resources */,
3602 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE)) 3660 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE))
3603 return NULL; 3661 return NULL;
3604 return context.release(); 3662 return context.release();
3605 } 3663 }
3606 } 3664 }
3607 3665
3666 std::string RenderViewImpl::ConstructFrameTree(
3667 WebKit::WebFrame* frame, bool exclude_subtree) {
3668 std::string json;
3669 WebFrame* f = frame->top();
3670 base::DictionaryValue tree;
3671
3672 FrameTree(f, exclude_subtree ? frame : NULL, &tree);
3673 base::JSONWriter::Write(&tree, &json);
3674 return json;
3675 }
3676
3608 void RenderViewImpl::EnsureMediaStreamImpl() { 3677 void RenderViewImpl::EnsureMediaStreamImpl() {
3609 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. 3678 if (!RenderThreadImpl::current()) // Will be NULL during unit tests.
3610 return; 3679 return;
3611 3680
3612 #if defined(ENABLE_WEBRTC) 3681 #if defined(ENABLE_WEBRTC)
3613 if (!p2p_socket_dispatcher_) 3682 if (!p2p_socket_dispatcher_)
3614 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); 3683 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this);
3615 3684
3616 if (!media_stream_dispatcher_) 3685 if (!media_stream_dispatcher_)
3617 media_stream_dispatcher_ = new MediaStreamDispatcher(this); 3686 media_stream_dispatcher_ = new MediaStreamDispatcher(this);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 } 3882 }
3814 delete channels; 3883 delete channels;
3815 } 3884 }
3816 3885
3817 int id = intents_host_->RegisterWebIntent(intentRequest); 3886 int id = intents_host_->RegisterWebIntent(intentRequest);
3818 Send(new IntentsHostMsg_WebIntentDispatch( 3887 Send(new IntentsHostMsg_WebIntentDispatch(
3819 routing_id_, intent_data, id)); 3888 routing_id_, intent_data, id));
3820 } 3889 }
3821 3890
3822 bool RenderViewImpl::willCheckAndDispatchMessageEvent( 3891 bool RenderViewImpl::willCheckAndDispatchMessageEvent(
3823 WebKit::WebFrame* source, 3892 WebKit::WebFrame* sourceFrame,
3893 WebKit::WebFrame* targetFrame,
3824 WebKit::WebSecurityOrigin target_origin, 3894 WebKit::WebSecurityOrigin target_origin,
3825 WebKit::WebDOMMessageEvent event) { 3895 WebKit::WebDOMMessageEvent event) {
3826 if (!is_swapped_out_) 3896 if (!is_swapped_out_)
3827 return false; 3897 return false;
3828 3898
3829 ViewMsg_PostMessage_Params params; 3899 ViewMsg_PostMessage_Params params;
3830 params.data = event.data().toString(); 3900 params.data = event.data().toString();
3831 params.source_origin = event.origin(); 3901 params.source_origin = event.origin();
3832 if (!target_origin.isNull()) 3902 if (!target_origin.isNull())
3833 params.target_origin = target_origin.toString(); 3903 params.target_origin = target_origin.toString();
3834 3904
3835 // Include the routing ID for the source frame, which the browser process 3905 // 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 3906 // will translate into the routing ID for the equivalent frame in the target
3837 // process. 3907 // process.
3838 // TODO(creis): Support source subframes.
3839 params.source_routing_id = MSG_ROUTING_NONE; 3908 params.source_routing_id = MSG_ROUTING_NONE;
3840 RenderViewImpl* source_view = FromWebView(source->view()); 3909 RenderViewImpl* source_view = FromWebView(sourceFrame->view());
3841 if (source_view) 3910 if (source_view)
3842 params.source_routing_id = source_view->routing_id(); 3911 params.source_routing_id = source_view->routing_id();
3912 params.source_frame_id = sourceFrame->identifier();
3913
3914 // Include the process, route, and frame IDs of the target frame. This allows
3915 // the browser to detect races between this message being sent and the target
3916 // frame no longer being valid.
3917 params.remote_process_id = remote_process_id_;
3918 params.remote_routing_id = remote_routing_id_;
3919
3920 std::map<int,int>::iterator it = frames_map_.find(targetFrame->identifier());
3921 if (it != frames_map_.end()) {
3922 params.remote_frame_id = it->second;
3923 } else {
3924 params.remote_frame_id = 0;
3925 }
3843 3926
3844 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); 3927 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params));
3845 return true; 3928 return true;
3846 } 3929 }
3847 3930
3848 void RenderViewImpl::willOpenSocketStream( 3931 void RenderViewImpl::willOpenSocketStream(
3849 WebSocketStreamHandle* handle) { 3932 WebSocketStreamHandle* handle) {
3850 SocketStreamHandleData::AddToHandle(handle, routing_id_); 3933 SocketStreamHandleData::AddToHandle(handle, routing_id_);
3851 } 3934 }
3852 3935
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
4562 4645
4563 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, 4646 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath,
4564 const string16& jscript, 4647 const string16& jscript,
4565 int id, 4648 int id,
4566 bool notify_result) { 4649 bool notify_result) {
4567 EvaluateScript(frame_xpath, jscript, id, notify_result); 4650 EvaluateScript(frame_xpath, jscript, id, notify_result);
4568 } 4651 }
4569 4652
4570 void RenderViewImpl::OnPostMessageEvent( 4653 void RenderViewImpl::OnPostMessageEvent(
4571 const ViewMsg_PostMessage_Params& params) { 4654 const ViewMsg_PostMessage_Params& params) {
4572 // TODO(creis): Support sending to subframes. 4655 // Find the frame, which is a target of this message. The source tags the
4573 WebFrame* frame = webview()->mainFrame(); 4656 // message with |remote_frame_id|, so use it to locate the frame.
4657 WebFrame* frame = FindFrameByID(webview()->mainFrame(),
4658 params.remote_frame_id);
4659 if (!frame)
4660 return;
4574 4661
4575 // Find the source frame if it exists. 4662 // Find the source frame if it exists.
4576 // TODO(creis): Support source subframes.
4577 WebFrame* source_frame = NULL; 4663 WebFrame* source_frame = NULL;
4578 if (params.source_routing_id != MSG_ROUTING_NONE) { 4664 if (params.source_routing_id != MSG_ROUTING_NONE) {
4579 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); 4665 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id);
4580 if (source_view) 4666 if (source_view)
4581 source_frame = source_view->webview()->mainFrame(); 4667 source_frame = source_view->GetFrameByRemoteID(params.source_frame_id);
4582 } 4668 }
4583 4669
4584 // Create an event with the message. The final parameter to initMessageEvent 4670 // Create an event with the message. The final parameter to initMessageEvent
4585 // is the last event ID, which is not used with postMessage. 4671 // is the last event ID, which is not used with postMessage.
4586 WebDOMEvent event = frame->document().createEvent("MessageEvent"); 4672 WebDOMEvent event = frame->document().createEvent("MessageEvent");
4587 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); 4673 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>();
4588 msg_event.initMessageEvent("message", 4674 msg_event.initMessageEvent("message",
4589 // |canBubble| and |cancellable| are always false 4675 // |canBubble| and |cancellable| are always false
4590 false, false, 4676 false, false,
4591 WebSerializedScriptValue::fromString(params.data), 4677 WebSerializedScriptValue::fromString(params.data),
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 // Synchronously run the unload handler before sending the ACK. 5006 // Synchronously run the unload handler before sending the ACK.
4921 webview()->dispatchUnloadEvent(); 5007 webview()->dispatchUnloadEvent();
4922 5008
4923 // Swap out and stop sending any IPC messages that are not ACKs. 5009 // Swap out and stop sending any IPC messages that are not ACKs.
4924 SetSwappedOut(true); 5010 SetSwappedOut(true);
4925 5011
4926 // Replace the page with a blank dummy URL. The unload handler will not be 5012 // 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. 5013 // 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 5014 // 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. 5015 // beforeunload handler. For now, we just run it a second time silently.
4930 NavigateToSwappedOutURL(); 5016 NavigateToSwappedOutURL(webview()->mainFrame(), NULL);
4931 5017
4932 // Let WebKit know that this view is hidden so it can drop resources and 5018 // Let WebKit know that this view is hidden so it can drop resources and
4933 // stop compositing. 5019 // stop compositing.
4934 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); 5020 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false);
4935 } 5021 }
4936 5022
4937 // Just echo back the params in the ACK. 5023 // Just echo back the params in the ACK.
4938 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); 5024 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params));
4939 } 5025 }
4940 5026
4941 void RenderViewImpl::NavigateToSwappedOutURL() { 5027 void RenderViewImpl::NavigateToSwappedOutURL(
5028 WebKit::WebFrame* frame,
5029 base::DictionaryValue* frame_tree) {
4942 // We use loadRequest instead of loadHTMLString because the former commits 5030 // We use loadRequest instead of loadHTMLString because the former commits
4943 // synchronously. Otherwise a new navigation can interrupt the navigation 5031 // synchronously. Otherwise a new navigation can interrupt the navigation
4944 // to content::kSwappedOutURL. If that happens to be to the page we had been 5032 // 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. 5033 // showing, then WebKit will never send a commit and we'll be left spinning.
4946 GURL swappedOutURL(content::kSwappedOutURL); 5034 GURL swappedOutURL(content::kSwappedOutURL);
4947 WebURLRequest request(swappedOutURL); 5035 WebURLRequest request(swappedOutURL);
4948 webview()->mainFrame()->loadRequest(request); 5036 frame->loadRequest(request);
5037
5038 // If a frame tree is specified, recursively recreate it using the data
5039 // in the current DictionaryValue.
5040 if (frame_tree == NULL)
5041 return;
5042
5043 string16 name;
5044 if (frame_tree->GetString("name", &name) && name != string16())
5045 frame->setName(name);
5046
5047 int remote_id;
5048 if (frame_tree->GetInteger("id", &remote_id))
5049 frames_map_.insert(std::pair<int, int>(frame->identifier(), remote_id));
5050
5051 ListValue* children;
5052 if (!frame_tree->GetList("subtree", &children))
5053 return;
5054
5055 base::DictionaryValue* child;
5056 for (size_t i = 0; i < children->GetSize(); ++i) {
5057 if (!children->GetDictionary(i, &child))
5058 continue;
5059 WebElement element = frame->document().createElement("iframe");
5060 if (frame->document().body().appendChild(element)) {
5061 WebFrame* subframe = WebFrame::fromFrameOwnerElement(element);
5062 if (subframe) {
5063 NavigateToSwappedOutURL(subframe, child);
5064 }
5065 }
5066 }
4949 } 5067 }
4950 5068
4951 void RenderViewImpl::OnClosePage() { 5069 void RenderViewImpl::OnClosePage() {
4952 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); 5070 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage());
4953 // TODO(creis): We'd rather use webview()->Close() here, but that currently 5071 // TODO(creis): We'd rather use webview()->Close() here, but that currently
4954 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs 5072 // 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 5073 // in the onunload handler from appearing. For now, we're bypassing that and
4956 // calling the FrameLoader's CloseURL method directly. This should be 5074 // 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 5075 // 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 5076 // to close that can run onunload is also useful for fixing
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
5798 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { 5916 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const {
5799 return !!RenderThreadImpl::current()->compositor_thread(); 5917 return !!RenderThreadImpl::current()->compositor_thread();
5800 } 5918 }
5801 5919
5802 void RenderViewImpl::OnJavaBridgeInit() { 5920 void RenderViewImpl::OnJavaBridgeInit() {
5803 DCHECK(!java_bridge_dispatcher_); 5921 DCHECK(!java_bridge_dispatcher_);
5804 #if defined(ENABLE_JAVA_BRIDGE) 5922 #if defined(ENABLE_JAVA_BRIDGE)
5805 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); 5923 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this);
5806 #endif 5924 #endif
5807 } 5925 }
5926
5927
5928 void RenderViewImpl::OnFrameTree(
5929 int process_id,
5930 int route_id,
5931 const std::string& frame_tree) {
5932 base::DictionaryValue* frames = NULL;
5933 scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree));
5934 if (tree.get() != NULL && tree->IsType(base::Value::TYPE_DICTIONARY))
5935 tree->GetAsDictionary(&frames);
5936
5937 updating_frame_tree_ = true;
5938 frames_map_.clear();
5939
5940 remote_process_id_ = process_id;
5941 remote_routing_id_ = route_id;
5942 NavigateToSwappedOutURL(webview()->mainFrame(), frames);
5943
5944 updating_frame_tree_ = false;
5945 }
5946
5947 WebKit::WebFrame* RenderViewImpl::GetFrameByRemoteID(int remote_frame_id) {
5948 WebKit::WebFrame* frame = NULL;
5949
5950 std::map<int, int>::iterator it = frames_map_.find(remote_frame_id);
5951 if (it == frames_map_.end())
5952 return NULL;
5953
5954 for (WebFrame* f = webview()->mainFrame(); f; f = f->traverseNext(false))
5955 if (f->identifier() == it->second)
5956 frame = f;
5957
5958 return frame;
5959 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698